zscaler-sdk-python 1.2.2__py3-none-any.whl → 1.2.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.
- zscaler/__init__.py +1 -1
- zscaler/helpers.py +26 -1
- zscaler/utils.py +19 -4
- zscaler/zcc/admin_user.py +7 -3
- zscaler/zcc/company.py +5 -4
- zscaler/zcc/devices.py +249 -121
- zscaler/zcc/fail_open_policy.py +29 -8
- zscaler/zcc/forwarding_profile.py +31 -9
- zscaler/zcc/models/admin_user.py +1 -1
- zscaler/zcc/models/devices.py +10 -2
- zscaler/zcc/models/getcompanyinfo.py +39 -23
- zscaler/zcc/models/webpolicy.py +528 -26
- zscaler/zcc/secrets.py +54 -32
- zscaler/zcc/trusted_networks.py +57 -6
- zscaler/zcc/web_app_service.py +0 -2
- zscaler/zcc/web_policy.py +41 -24
- zscaler/zcc/web_privacy.py +22 -3
- zscaler/zcc/zcc_service.py +0 -9
- zscaler/zia/legacy.py +10 -0
- zscaler/zia/{cloud_apps.py → shadow_it_report.py} +28 -21
- zscaler/zia/zia_service.py +9 -0
- {zscaler_sdk_python-1.2.2.dist-info → zscaler_sdk_python-1.2.3.dist-info}/METADATA +1 -1
- {zscaler_sdk_python-1.2.2.dist-info → zscaler_sdk_python-1.2.3.dist-info}/RECORD +25 -26
- zscaler/zcc/manage_pass.py +0 -65
- {zscaler_sdk_python-1.2.2.dist-info → zscaler_sdk_python-1.2.3.dist-info}/LICENSE.md +0 -0
- {zscaler_sdk_python-1.2.2.dist-info → zscaler_sdk_python-1.2.3.dist-info}/WHEEL +0 -0
zscaler/__init__.py
CHANGED
zscaler/helpers.py
CHANGED
|
@@ -73,6 +73,7 @@ def to_snake_case(string):
|
|
|
73
73
|
"computeDeviceGroupsForZAD": "compute_device_groups_for_zad",
|
|
74
74
|
"computeDeviceGroupsForZAD": "compute_device_groups_for_zad",
|
|
75
75
|
"deleteDHCPOption121RoutesVisibility": "delete_dhcp_option121_routes_visibility",
|
|
76
|
+
"deleteDHCPOption121Routes": "delete_dhcp_option121_routes",
|
|
76
77
|
"enableOneIDAdminMigrationChanges": "enable_one_id_admin_migration_changes",
|
|
77
78
|
"purgeKerberosPreferredDCCacheVisibility": "purge_kerberos_preferred_dc_cache_visibility",
|
|
78
79
|
"slowRolloutZCC": "slow_rollout_zcc",
|
|
@@ -105,6 +106,18 @@ def to_snake_case(string):
|
|
|
105
106
|
"defaultProtocolForZPA": "default_protocol_for_zpa",
|
|
106
107
|
"tunnelTwoForiOSDevices": "tunnel_two_fori_os_devices",
|
|
107
108
|
"prioritizeIPv4OverIpv6": "prioritize_ipv4_over_ipv6",
|
|
109
|
+
"disableParallelIpv4AndIPv6": "disable_parallel_ipv4_and_ipv6",
|
|
110
|
+
"computeDeviceGroupsForZDX ": "compute_device_groups_for_zdx",
|
|
111
|
+
"logoutZCCForZDXService": "logout_zcc_for_zdx_service",
|
|
112
|
+
"enableZpaDR": "enable_zpa_dr",
|
|
113
|
+
"ziaRSAPubKeyName": "zia_rsa_pub_key_name",
|
|
114
|
+
"ziaRSAPubKey": "zia_rsa_pub_key",
|
|
115
|
+
"zpaRSAPubKeyName": "zpa_rsa_pub_key_name",
|
|
116
|
+
"zpaRSAPubKey": "zpa_rsa_pub_key",
|
|
117
|
+
"truncate_large_udpdns_response": "truncateLargeUDPDNSResponse",
|
|
118
|
+
"enableZCCRevert": "enable_zcc_revert",
|
|
119
|
+
"enableZiaDR": "enable_zia_dr",
|
|
120
|
+
"purge_kerberos_preferred_dc_cache": "purgeKerberosPreferredDCCache"
|
|
108
121
|
}
|
|
109
122
|
|
|
110
123
|
if string in FIELD_EXCEPTIONS:
|
|
@@ -217,7 +230,19 @@ def to_lower_camel_case(string):
|
|
|
217
230
|
"default_protocol_for_zpa": "defaultProtocolForZPA",
|
|
218
231
|
"tunnelTwoForiOSDevices": "tunnel_two_fori_os_devices",
|
|
219
232
|
"prioritize_ipv4_over_ipv6": "prioritizeIPv4OverIpv6",
|
|
220
|
-
|
|
233
|
+
"disable_parallel_ipv4_and_ipv6": "disableParallelIpv4AndIPv6",
|
|
234
|
+
"compute_device_groups_for_zdx": "computeDeviceGroupsForZDX",
|
|
235
|
+
"logout_zcc_for_zdx_service ": "logoutZCCForZDXService",
|
|
236
|
+
"enable_zpa_dr": "enableZpaDR",
|
|
237
|
+
"zia_rsa_pub_key_name": "ziaRSAPubKeyName",
|
|
238
|
+
"zia_rsa_pub_key": "ziaRSAPubKey",
|
|
239
|
+
"zpa_rsa_pub_key_name": "zpaRSAPubKeyName",
|
|
240
|
+
"zpa_rsa_pub_key": "zpaRSAPubKey",
|
|
241
|
+
"truncateLargeUDPDNSResponse": "truncate_large_udpdns_response",
|
|
242
|
+
"enable_zcc_revert": "enableZCCRevert",
|
|
243
|
+
"delete_dhcp_option121_routes": "deleteDHCPOption121Routes",
|
|
244
|
+
"enableZiaDR": "enable_zia_dr",
|
|
245
|
+
"purgeKerberosPreferredDCCache": "purge_kerberos_preferred_dc_cache"
|
|
221
246
|
}
|
|
222
247
|
|
|
223
248
|
if string in FIELD_EXCEPTIONS:
|
zscaler/utils.py
CHANGED
|
@@ -790,8 +790,8 @@ def zcc_param_mapper(func):
|
|
|
790
790
|
mapped_params = {}
|
|
791
791
|
|
|
792
792
|
# Normalize and map os_types
|
|
793
|
-
if "
|
|
794
|
-
os_raw = query_params["
|
|
793
|
+
if "os_type" in query_params:
|
|
794
|
+
os_raw = query_params["os_type"]
|
|
795
795
|
if isinstance(os_raw, str):
|
|
796
796
|
os_raw = [os_raw] # ✅ support single string value
|
|
797
797
|
|
|
@@ -801,8 +801,23 @@ def zcc_param_mapper(func):
|
|
|
801
801
|
if zcc_param_map["os"].get(os_type.lower())
|
|
802
802
|
]
|
|
803
803
|
if not mapped:
|
|
804
|
-
raise ValueError("Invalid `
|
|
805
|
-
mapped_params["
|
|
804
|
+
raise ValueError("Invalid `os_type` provided.")
|
|
805
|
+
mapped_params["osType"] = ",".join(mapped)
|
|
806
|
+
|
|
807
|
+
# Normalize and map os_types
|
|
808
|
+
if "device_type" in query_params:
|
|
809
|
+
os_raw = query_params["device_type"]
|
|
810
|
+
if isinstance(os_raw, str):
|
|
811
|
+
os_raw = [os_raw] # ✅ support single string value
|
|
812
|
+
|
|
813
|
+
mapped = [
|
|
814
|
+
str(zcc_param_map["os"].get(os_type.lower()))
|
|
815
|
+
for os_type in os_raw
|
|
816
|
+
if zcc_param_map["os"].get(os_type.lower())
|
|
817
|
+
]
|
|
818
|
+
if not mapped:
|
|
819
|
+
raise ValueError("Invalid `device_type` provided.")
|
|
820
|
+
mapped_params["deviceType"] = ",".join(mapped)
|
|
806
821
|
|
|
807
822
|
# Normalize and map registration_types
|
|
808
823
|
if "registration_types" in query_params:
|
zscaler/zcc/admin_user.py
CHANGED
|
@@ -139,9 +139,13 @@ class AdminUserAPI(APIClient):
|
|
|
139
139
|
Examples:
|
|
140
140
|
Prints all admin roles in the Client Connector Portal to the console:
|
|
141
141
|
|
|
142
|
-
>>>
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
>>> role_list, _, err = client.zcc.admin_user.list_admin_roles()
|
|
143
|
+
>>> if err:
|
|
144
|
+
... print(f"Error listing admin roles: {err}")
|
|
145
|
+
... return
|
|
146
|
+
... print(f"Total admin roles found: {len(role_list)}")
|
|
147
|
+
... for role in role_list:
|
|
148
|
+
... print(role.as_dict())
|
|
145
149
|
"""
|
|
146
150
|
http_method = "get".upper()
|
|
147
151
|
api_url = format_url(
|
zscaler/zcc/company.py
CHANGED
|
@@ -69,8 +69,9 @@ class CompanyInfoAPI(APIClient):
|
|
|
69
69
|
return (None, response, error)
|
|
70
70
|
|
|
71
71
|
try:
|
|
72
|
-
result =
|
|
72
|
+
result = []
|
|
73
|
+
for item in response.get_results():
|
|
74
|
+
result.append(GetCompanyInfo(self.form_response_body(item)))
|
|
73
75
|
except Exception as error:
|
|
74
|
-
return None, response, error
|
|
75
|
-
|
|
76
|
-
return result, response, None
|
|
76
|
+
return (None, response, error)
|
|
77
|
+
return (result, response, None)
|
zscaler/zcc/devices.py
CHANGED
|
@@ -17,6 +17,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
17
17
|
from zscaler.api_client import APIClient
|
|
18
18
|
from zscaler.request_executor import RequestExecutor
|
|
19
19
|
from zscaler.utils import format_url, zcc_param_map, zcc_param_mapper
|
|
20
|
+
from zscaler.helpers import convert_keys_to_camel_case
|
|
20
21
|
from zscaler.zcc.models.devices import Device
|
|
21
22
|
from zscaler.zcc.models.devices import ForceRemoveDevices
|
|
22
23
|
from zscaler.zcc.models.devices import SetDeviceCleanupInfo
|
|
@@ -32,58 +33,188 @@ class DevicesAPI(APIClient):
|
|
|
32
33
|
self._request_executor: RequestExecutor = request_executor
|
|
33
34
|
self._zcc_base_endpoint = "/zcc/papi/public/v1"
|
|
34
35
|
|
|
35
|
-
def download_devices(
|
|
36
|
-
self,
|
|
37
|
-
filename: str = None,
|
|
38
|
-
os_types: list = None,
|
|
39
|
-
registration_types: list = None,
|
|
40
|
-
):
|
|
36
|
+
def download_devices(self, query_params=None, filename: str = None):
|
|
41
37
|
"""
|
|
42
38
|
Downloads the list of devices as a CSV file from the ZCC portal.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
query_params (dict, optional): A dictionary containing supported filters:
|
|
42
|
+
``[query_params.os_types]`` {str}: Filter by device operating system type. Valid options are:
|
|
43
|
+
- ios
|
|
44
|
+
- android
|
|
45
|
+
- windows
|
|
46
|
+
- macos
|
|
47
|
+
- linux
|
|
48
|
+
``[query_params.registration_types]`` {str}: Filter by device operating system type. Valid options are:
|
|
49
|
+
- all
|
|
50
|
+
- registered
|
|
51
|
+
- unregistered
|
|
52
|
+
- removal_pending
|
|
53
|
+
- removed
|
|
54
|
+
- quarantined
|
|
55
|
+
|
|
56
|
+
filename (str, optional): Custom filename for the CSV file. Defaults to timestamped name.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
str: Path to the downloaded CSV file.
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
Download list of devices as a CSV:
|
|
63
|
+
|
|
64
|
+
>>> try:
|
|
65
|
+
... filename = client.zcc.devices.download_devices(
|
|
66
|
+
... query_params={
|
|
67
|
+
... "os_types": ["windows"],
|
|
68
|
+
... "registration_types": ["unregistered"]
|
|
69
|
+
... },
|
|
70
|
+
... filename="unregistered_devices.csv"
|
|
71
|
+
... )
|
|
72
|
+
... print(f"Devices downloaded successfully: {filename}")
|
|
73
|
+
... except Exception as e:
|
|
74
|
+
... print(f"Error during download: {e}")
|
|
43
75
|
"""
|
|
76
|
+
|
|
77
|
+
query_params = query_params or {}
|
|
78
|
+
|
|
44
79
|
if not filename:
|
|
45
80
|
filename = f"zcc-devices-{datetime.now().strftime('%Y%m%d-%H_%M_%S')}.csv"
|
|
46
81
|
|
|
82
|
+
# Translate os_types
|
|
47
83
|
params = {}
|
|
48
|
-
|
|
49
|
-
# Handle OS types
|
|
84
|
+
os_types = query_params.get("os_types")
|
|
50
85
|
if os_types:
|
|
51
86
|
os_types_resolved = [str(zcc_param_map["os"].get(item)) for item in os_types if zcc_param_map["os"].get(item)]
|
|
52
87
|
if not os_types_resolved:
|
|
53
88
|
raise ValueError("Invalid os_type specified.")
|
|
54
89
|
params["osTypes"] = ",".join(os_types_resolved)
|
|
55
90
|
|
|
56
|
-
#
|
|
91
|
+
# Translate registration_types
|
|
92
|
+
registration_types = query_params.get("registration_types")
|
|
57
93
|
if registration_types:
|
|
58
94
|
reg_types_resolved = [
|
|
59
|
-
str(zcc_param_map["reg_type"].get(item))
|
|
95
|
+
str(zcc_param_map["reg_type"].get(item))
|
|
96
|
+
for item in registration_types
|
|
97
|
+
if zcc_param_map["reg_type"].get(item)
|
|
60
98
|
]
|
|
61
99
|
if not reg_types_resolved:
|
|
62
100
|
raise ValueError("Invalid registration_type specified.")
|
|
63
101
|
params["registrationTypes"] = ",".join(reg_types_resolved)
|
|
64
102
|
|
|
65
|
-
# Correct the API URL
|
|
66
103
|
http_method = "get".upper()
|
|
67
104
|
api_url = format_url(f"{self._zcc_base_endpoint}/downloadDevices")
|
|
68
105
|
|
|
69
|
-
|
|
70
|
-
|
|
106
|
+
request, error = self._request_executor.create_request(
|
|
107
|
+
http_method,
|
|
108
|
+
api_url,
|
|
109
|
+
params=params,
|
|
110
|
+
headers={"Accept": "*/*"}
|
|
111
|
+
)
|
|
112
|
+
|
|
71
113
|
if error:
|
|
72
114
|
raise Exception("Error creating request for downloading devices.")
|
|
73
115
|
|
|
74
|
-
# Execute request and download file
|
|
75
116
|
response, error = self._request_executor.execute(request, return_raw_response=True)
|
|
76
117
|
if error or response is None:
|
|
77
118
|
raise Exception("Error executing request for downloading devices.")
|
|
78
119
|
|
|
79
|
-
# Validate the response content
|
|
80
120
|
content_type = response.headers.get("Content-Type", "").lower()
|
|
121
|
+
if not content_type.startswith("application/octet-stream") and not response.text.startswith('"User","Device type"'):
|
|
122
|
+
raise Exception("Invalid response content type or unexpected response format.")
|
|
123
|
+
|
|
124
|
+
with open(filename, "wb") as f:
|
|
125
|
+
f.write(response.content)
|
|
126
|
+
|
|
127
|
+
return filename
|
|
128
|
+
|
|
129
|
+
def download_service_status(self, query_params=None, filename: str = None):
|
|
130
|
+
"""
|
|
131
|
+
Downloads service status for all devices from the ZCC portal.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
query_params (dict, optional): A dictionary containing supported filters:
|
|
135
|
+
Args:
|
|
136
|
+
query_params (dict, optional): A dictionary containing supported filters:
|
|
137
|
+
``[query_params.os_types]`` {str}: Filter by device operating system type. Valid options are:
|
|
138
|
+
- ios
|
|
139
|
+
- android
|
|
140
|
+
- windows
|
|
141
|
+
- macos
|
|
142
|
+
- linux
|
|
143
|
+
``[query_params.registration_types]`` {str}: Filter by device operating system type. Valid options are:
|
|
144
|
+
- all
|
|
145
|
+
- registered
|
|
146
|
+
- unregistered
|
|
147
|
+
- removal_pending
|
|
148
|
+
- removed
|
|
149
|
+
- quarantined
|
|
150
|
+
|
|
151
|
+
filename (str, optional): Custom filename for the CSV file. Defaults to timestamped name.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
str: Path to the downloaded CSV file.
|
|
81
155
|
|
|
82
|
-
|
|
156
|
+
Examples:
|
|
157
|
+
Download list of devices as a CSV:
|
|
158
|
+
|
|
159
|
+
>>> try:
|
|
160
|
+
... filename = client.zcc.devices.download_service_status(
|
|
161
|
+
... query_params={
|
|
162
|
+
... "os_types": ["windows"],
|
|
163
|
+
... "registration_types": ["unregistered"]
|
|
164
|
+
... },
|
|
165
|
+
... filename="unregistered_devices.csv"
|
|
166
|
+
... )
|
|
167
|
+
... print(f"Device Service Status downloaded successfully: {filename}")
|
|
168
|
+
... except Exception as e:
|
|
169
|
+
... print(f"Error during download: {e}")
|
|
170
|
+
"""
|
|
171
|
+
from datetime import datetime
|
|
172
|
+
|
|
173
|
+
query_params = query_params or {}
|
|
174
|
+
|
|
175
|
+
if not filename:
|
|
176
|
+
filename = f"zcc-service-status-{datetime.now().strftime('%Y%m%d-%H_%M_%S')}.csv"
|
|
177
|
+
|
|
178
|
+
params = {}
|
|
179
|
+
os_types = query_params.get("os_types")
|
|
180
|
+
if os_types:
|
|
181
|
+
os_types_resolved = [str(zcc_param_map["os"].get(item)) for item in os_types if zcc_param_map["os"].get(item)]
|
|
182
|
+
if not os_types_resolved:
|
|
183
|
+
raise ValueError("Invalid os_type specified.")
|
|
184
|
+
params["osTypes"] = ",".join(os_types_resolved)
|
|
185
|
+
|
|
186
|
+
registration_types = query_params.get("registration_types")
|
|
187
|
+
if registration_types:
|
|
188
|
+
reg_types_resolved = [
|
|
189
|
+
str(zcc_param_map["reg_type"].get(item))
|
|
190
|
+
for item in registration_types
|
|
191
|
+
if zcc_param_map["reg_type"].get(item)
|
|
192
|
+
]
|
|
193
|
+
if not reg_types_resolved:
|
|
194
|
+
raise ValueError("Invalid registration_type specified.")
|
|
195
|
+
params["registrationTypes"] = ",".join(reg_types_resolved)
|
|
196
|
+
|
|
197
|
+
http_method = "get".upper()
|
|
198
|
+
api_url = format_url(f"{self._zcc_base_endpoint}/downloadServiceStatus")
|
|
199
|
+
|
|
200
|
+
request, error = self._request_executor.create_request(
|
|
201
|
+
http_method,
|
|
202
|
+
api_url,
|
|
203
|
+
params=params,
|
|
204
|
+
headers={"Accept": "*/*"}
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
if error:
|
|
208
|
+
raise Exception("Error creating request for downloading service status.")
|
|
209
|
+
|
|
210
|
+
response, error = self._request_executor.execute(request, return_raw_response=True)
|
|
211
|
+
if error or response is None:
|
|
212
|
+
raise Exception("Error executing request for downloading service status.")
|
|
213
|
+
|
|
214
|
+
content_type = response.headers.get("Content-Type", "").lower()
|
|
83
215
|
if not content_type.startswith("application/octet-stream") and not response.text.startswith('"User","Device type"'):
|
|
84
216
|
raise Exception("Invalid response content type or unexpected response format.")
|
|
85
217
|
|
|
86
|
-
# Save file to disk
|
|
87
218
|
with open(filename, "wb") as f:
|
|
88
219
|
f.write(response.content)
|
|
89
220
|
|
|
@@ -147,7 +278,7 @@ class DevicesAPI(APIClient):
|
|
|
147
278
|
return (None, response, error)
|
|
148
279
|
|
|
149
280
|
try:
|
|
150
|
-
result = response.get_results()
|
|
281
|
+
result = response.get_results()
|
|
151
282
|
except Exception as error:
|
|
152
283
|
return None, response, error
|
|
153
284
|
|
|
@@ -166,9 +297,12 @@ class DevicesAPI(APIClient):
|
|
|
166
297
|
Examples:
|
|
167
298
|
Prints all devices in the Client Connector Portal to the console:
|
|
168
299
|
|
|
169
|
-
>>>
|
|
170
|
-
|
|
171
|
-
|
|
300
|
+
>>> devices, _, err = client.zcc.devices.get_device_cleanup_info()
|
|
301
|
+
>>> if err:
|
|
302
|
+
... print(f"Error fetching device clean up: {err}")
|
|
303
|
+
... return
|
|
304
|
+
... print("Device clean up fetched successfully.")
|
|
305
|
+
... print(devices)
|
|
172
306
|
"""
|
|
173
307
|
http_method = "get".upper()
|
|
174
308
|
api_url = format_url(
|
|
@@ -191,7 +325,7 @@ class DevicesAPI(APIClient):
|
|
|
191
325
|
return (None, response, error)
|
|
192
326
|
|
|
193
327
|
try:
|
|
194
|
-
result = response.get_results()
|
|
328
|
+
result = response.get_results()
|
|
195
329
|
except Exception as error:
|
|
196
330
|
return None, response, error
|
|
197
331
|
|
|
@@ -206,6 +340,20 @@ class DevicesAPI(APIClient):
|
|
|
206
340
|
|
|
207
341
|
Returns:
|
|
208
342
|
tuple: A tuple containing the updated Device Cleaup Information, response, and error.
|
|
343
|
+
|
|
344
|
+
Examples:
|
|
345
|
+
Updated Device Cleaup Information:
|
|
346
|
+
|
|
347
|
+
>>> device, _, err = client.zcc.devices.update_device_cleanup_info(
|
|
348
|
+
... active=1,
|
|
349
|
+
... force_remove_type=1,
|
|
350
|
+
... device_exceed_limit=16
|
|
351
|
+
... )
|
|
352
|
+
>>> if err:
|
|
353
|
+
... print(f"Error fetching device cleanup info: {err}")
|
|
354
|
+
... return
|
|
355
|
+
... print("Current device cleanup info fetched successfully.")
|
|
356
|
+
... print(device)
|
|
209
357
|
"""
|
|
210
358
|
http_method = "put".upper()
|
|
211
359
|
api_url = format_url(
|
|
@@ -218,12 +366,10 @@ class DevicesAPI(APIClient):
|
|
|
218
366
|
|
|
219
367
|
body.update(kwargs)
|
|
220
368
|
|
|
221
|
-
# Create the request
|
|
222
369
|
request, error = self._request_executor.create_request(http_method, api_url, body, {}, {})
|
|
223
370
|
if error:
|
|
224
371
|
return (None, None, error)
|
|
225
372
|
|
|
226
|
-
# Execute the request
|
|
227
373
|
response, error = self._request_executor.execute(request, SetDeviceCleanupInfo)
|
|
228
374
|
if error:
|
|
229
375
|
return (None, response, error)
|
|
@@ -254,7 +400,7 @@ class DevicesAPI(APIClient):
|
|
|
254
400
|
... return
|
|
255
401
|
... for device in details:
|
|
256
402
|
... print(device.as_dict())
|
|
257
|
-
|
|
403
|
+
|
|
258
404
|
Prints all devices in the Client Connector Portal to the console:
|
|
259
405
|
|
|
260
406
|
>>> details, _, err = client.zcc.devices.get_device_details(
|
|
@@ -293,80 +439,32 @@ class DevicesAPI(APIClient):
|
|
|
293
439
|
return (None, response, error)
|
|
294
440
|
return (result, response, None)
|
|
295
441
|
|
|
296
|
-
def
|
|
297
|
-
self,
|
|
298
|
-
filename: str = None,
|
|
299
|
-
os_types: list = None,
|
|
300
|
-
registration_types: list = None,
|
|
301
|
-
):
|
|
302
|
-
"""
|
|
303
|
-
Downloads service status for all devices from the ZCC portal.
|
|
304
|
-
"""
|
|
305
|
-
if not filename:
|
|
306
|
-
filename = f"zcc-devices-{datetime.now().strftime('%Y%m%d-%H_%M_%S')}.csv"
|
|
307
|
-
|
|
308
|
-
params = {}
|
|
309
|
-
|
|
310
|
-
# Handle OS types
|
|
311
|
-
if os_types:
|
|
312
|
-
os_types_resolved = [str(zcc_param_map["os"].get(item)) for item in os_types if zcc_param_map["os"].get(item)]
|
|
313
|
-
if not os_types_resolved:
|
|
314
|
-
raise ValueError("Invalid os_type specified.")
|
|
315
|
-
params["osTypes"] = ",".join(os_types_resolved)
|
|
316
|
-
|
|
317
|
-
# Handle Registration types
|
|
318
|
-
if registration_types:
|
|
319
|
-
reg_types_resolved = [
|
|
320
|
-
str(zcc_param_map["reg_type"].get(item)) for item in registration_types if zcc_param_map["reg_type"].get(item)
|
|
321
|
-
]
|
|
322
|
-
if not reg_types_resolved:
|
|
323
|
-
raise ValueError("Invalid registration_type specified.")
|
|
324
|
-
params["registrationTypes"] = ",".join(reg_types_resolved)
|
|
325
|
-
|
|
326
|
-
# Correct the API URL
|
|
327
|
-
http_method = "get".upper()
|
|
328
|
-
api_url = format_url(f"{self._zcc_base_endpoint}/downloadServiceStatus")
|
|
329
|
-
|
|
330
|
-
# Create the request properly
|
|
331
|
-
request, error = self._request_executor.create_request(http_method, api_url, params=params)
|
|
332
|
-
if error:
|
|
333
|
-
raise Exception("Error creating request for downloading devices.")
|
|
334
|
-
|
|
335
|
-
# Execute request and download file
|
|
336
|
-
response, error = self._request_executor.execute(request, return_raw_response=True)
|
|
337
|
-
if error or response is None:
|
|
338
|
-
raise Exception("Error executing request for downloading devices.")
|
|
339
|
-
|
|
340
|
-
# Validate the response content
|
|
341
|
-
content_type = response.headers.get("Content-Type", "").lower()
|
|
342
|
-
|
|
343
|
-
# Check for valid CSV-like content
|
|
344
|
-
if not content_type.startswith("application/octet-stream") and not response.text.startswith('"User","Device type"'):
|
|
345
|
-
raise Exception("Invalid response content type or unexpected response format.")
|
|
346
|
-
|
|
347
|
-
# Save file to disk
|
|
348
|
-
with open(filename, "wb") as f:
|
|
349
|
-
f.write(response.content)
|
|
350
|
-
|
|
351
|
-
return filename
|
|
352
|
-
|
|
353
|
-
def remove_devices(self, query_params=None) -> tuple:
|
|
442
|
+
def remove_devices(self, query_params=None, **kwargs) -> tuple:
|
|
354
443
|
"""
|
|
355
444
|
Remove of the devices from the Client Connector Portal.
|
|
356
445
|
|
|
357
446
|
Args:
|
|
358
447
|
query_params {dict}: Map of query parameters for the request.
|
|
359
|
-
``[query_params.page_size]`` {int}: Specifies the page size.
|
|
448
|
+
``[query_params.page_size]`` {int}: Specifies the page size. If not provided, the default page size is 30.
|
|
449
|
+
The max page size is 5000.
|
|
360
450
|
|
|
361
451
|
Returns:
|
|
362
452
|
:obj:`list`: Remove devices from the Client Connector Portal.
|
|
363
453
|
|
|
364
454
|
Examples:
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
>>>
|
|
368
|
-
...
|
|
369
|
-
|
|
455
|
+
Removes devices in the Client Connector Portal to the console:
|
|
456
|
+
|
|
457
|
+
>>> remove_devices, _, error = client.zcc.devices.remove_devices(
|
|
458
|
+
... client_connector_version=['3.0.0.57'],
|
|
459
|
+
... os_type='3',
|
|
460
|
+
... udids='VMware-42-02-38-a5-5f-9c-86-39-ff-5a-d0-60-5c-35-68-90:D630C3617830C5C0B2DDE986EA7D994324C4EC1D',
|
|
461
|
+
... username='jdoe@acme.com'
|
|
462
|
+
... )
|
|
463
|
+
>>> if error:
|
|
464
|
+
... print(f"Error removing device: {error}")
|
|
465
|
+
... return
|
|
466
|
+
... for device in remove_devices:
|
|
467
|
+
... print(f"Removed device: {device.as_dict()}")
|
|
370
468
|
"""
|
|
371
469
|
http_method = "post".upper()
|
|
372
470
|
api_url = format_url(
|
|
@@ -378,16 +476,19 @@ class DevicesAPI(APIClient):
|
|
|
378
476
|
|
|
379
477
|
query_params = query_params or {}
|
|
380
478
|
|
|
381
|
-
|
|
382
|
-
body = {}
|
|
383
|
-
headers = {}
|
|
479
|
+
body = kwargs
|
|
384
480
|
|
|
385
|
-
request, error = self._request_executor.create_request(
|
|
481
|
+
request, error = self._request_executor.create_request(
|
|
482
|
+
method=http_method,
|
|
483
|
+
endpoint=api_url,
|
|
484
|
+
body=body,
|
|
485
|
+
params=query_params
|
|
486
|
+
)
|
|
386
487
|
|
|
387
488
|
if error:
|
|
388
489
|
return (None, None, error)
|
|
389
490
|
|
|
390
|
-
response, error = self._request_executor.execute(request)
|
|
491
|
+
response, error = self._request_executor.execute(request, ForceRemoveDevices)
|
|
391
492
|
if error:
|
|
392
493
|
return (None, response, error)
|
|
393
494
|
|
|
@@ -399,23 +500,32 @@ class DevicesAPI(APIClient):
|
|
|
399
500
|
return (None, response, error)
|
|
400
501
|
return (result, response, None)
|
|
401
502
|
|
|
402
|
-
def force_remove_devices(self, query_params=None) -> tuple:
|
|
503
|
+
def force_remove_devices(self, query_params=None, **kwargs) -> tuple:
|
|
403
504
|
"""
|
|
404
505
|
Force remove of the devices from the Client Connector Portal.
|
|
405
506
|
|
|
406
507
|
Args:
|
|
407
508
|
query_params {dict}: Map of query parameters for the request.
|
|
408
|
-
``[query_params.page_size]`` {int}: Specifies the page size.
|
|
509
|
+
``[query_params.page_size]`` {int}: Specifies the page size. If not provided, the default page size is 30.
|
|
510
|
+
The max page size is 5000.
|
|
409
511
|
|
|
410
512
|
Returns:
|
|
411
|
-
:obj:`list`:
|
|
513
|
+
:obj:`list`: Forces the removal of devices from the Client Connector Portal.
|
|
412
514
|
|
|
413
515
|
Examples:
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
>>>
|
|
417
|
-
...
|
|
418
|
-
|
|
516
|
+
Removes devices in the Client Connector Portal to the console:
|
|
517
|
+
|
|
518
|
+
>>> remove_devices, _, error = client.zcc.devices.force_remove_devices(
|
|
519
|
+
... client_connector_version=['3.0.0.57'],
|
|
520
|
+
... os_type='3',
|
|
521
|
+
... udids='VMware-42-02-38-a5-5f-9c-86-39-ff-5a-d0-60-5c-35-68-90:D630C3617830C5C0B2DDE986EA7D994324C4EC1D',
|
|
522
|
+
... username='jdoe@acme.com'
|
|
523
|
+
... )
|
|
524
|
+
>>> if error:
|
|
525
|
+
... print(f"Error removing device: {error}")
|
|
526
|
+
... return
|
|
527
|
+
... for device in remove_devices:
|
|
528
|
+
... print(f"Removed device: {device.as_dict()}")
|
|
419
529
|
"""
|
|
420
530
|
http_method = "post".upper()
|
|
421
531
|
api_url = format_url(
|
|
@@ -427,16 +537,19 @@ class DevicesAPI(APIClient):
|
|
|
427
537
|
|
|
428
538
|
query_params = query_params or {}
|
|
429
539
|
|
|
430
|
-
|
|
431
|
-
body = {}
|
|
432
|
-
headers = {}
|
|
540
|
+
body = kwargs
|
|
433
541
|
|
|
434
|
-
request, error = self._request_executor.create_request(
|
|
542
|
+
request, error = self._request_executor.create_request(
|
|
543
|
+
method=http_method,
|
|
544
|
+
endpoint=api_url,
|
|
545
|
+
body=body,
|
|
546
|
+
params=query_params
|
|
547
|
+
)
|
|
435
548
|
|
|
436
549
|
if error:
|
|
437
550
|
return (None, None, error)
|
|
438
551
|
|
|
439
|
-
response, error = self._request_executor.execute(request)
|
|
552
|
+
response, error = self._request_executor.execute(request, ForceRemoveDevices)
|
|
440
553
|
if error:
|
|
441
554
|
return (None, response, error)
|
|
442
555
|
|
|
@@ -448,10 +561,15 @@ class DevicesAPI(APIClient):
|
|
|
448
561
|
return (None, response, error)
|
|
449
562
|
return (result, response, None)
|
|
450
563
|
|
|
451
|
-
def remove_machine_tunnel(self) -> tuple:
|
|
564
|
+
def remove_machine_tunnel(self, query_params=None, **kwargs) -> tuple:
|
|
452
565
|
"""
|
|
453
566
|
Remove machine tunnel devices from the Client Connector Portal.
|
|
454
567
|
|
|
568
|
+
Args:
|
|
569
|
+
query_params {dict}: Map of query parameters for the request.
|
|
570
|
+
``[query_params.hostname]`` {int}: Comma-separated list of hostnames for the device.
|
|
571
|
+
``[query_params.machine_token]`` {int}: Comma-separated list of hostnames for the device.
|
|
572
|
+
|
|
455
573
|
Keyword Args:
|
|
456
574
|
hostnames (str): The hostname of the machine tunnel to be removed.
|
|
457
575
|
machine_token (str): The machine tunnel token to be removed.
|
|
@@ -460,11 +578,15 @@ class DevicesAPI(APIClient):
|
|
|
460
578
|
:obj:`list`: Remove machine tunnel devices from the Client Connector Portal.
|
|
461
579
|
|
|
462
580
|
Examples:
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
>>> for tunnel in zcc.devices.remove_machine_tunnel():
|
|
466
|
-
... print(tunnel)
|
|
581
|
+
Removes machine tunnels in the Client Connector Portal to the console:
|
|
467
582
|
|
|
583
|
+
>>> remove_tunnels, _, error = client.zcc.devices.remove_machine_tunnel(
|
|
584
|
+
... host_names=['FXJ14JLFQW'],
|
|
585
|
+
... )
|
|
586
|
+
>>> if error:
|
|
587
|
+
... print(f"Error removing machine tunnel: {error}")
|
|
588
|
+
... return
|
|
589
|
+
... print("Removed machine tunnel:", remove_tunnels)
|
|
468
590
|
"""
|
|
469
591
|
http_method = "post".upper()
|
|
470
592
|
api_url = format_url(
|
|
@@ -474,22 +596,28 @@ class DevicesAPI(APIClient):
|
|
|
474
596
|
"""
|
|
475
597
|
)
|
|
476
598
|
|
|
477
|
-
|
|
599
|
+
query_params = convert_keys_to_camel_case(query_params or {})
|
|
600
|
+
body = convert_keys_to_camel_case(kwargs or {})
|
|
478
601
|
headers = {}
|
|
479
602
|
|
|
480
|
-
request, error = self._request_executor.create_request(
|
|
603
|
+
request, error = self._request_executor.create_request(
|
|
604
|
+
http_method,
|
|
605
|
+
api_url,
|
|
606
|
+
body=body,
|
|
607
|
+
headers=headers,
|
|
608
|
+
params=query_params,
|
|
609
|
+
)
|
|
481
610
|
|
|
482
611
|
if error:
|
|
483
|
-
return
|
|
612
|
+
return None, None, error
|
|
484
613
|
|
|
485
614
|
response, error = self._request_executor.execute(request)
|
|
486
615
|
if error:
|
|
487
|
-
return
|
|
616
|
+
return None, response, error
|
|
488
617
|
|
|
489
618
|
try:
|
|
490
|
-
result =
|
|
491
|
-
for item in response.get_results():
|
|
492
|
-
result.append((self.form_response_body(item)))
|
|
619
|
+
result = self.form_response_body(response.get_body())
|
|
493
620
|
except Exception as error:
|
|
494
|
-
return
|
|
495
|
-
|
|
621
|
+
return None, response, error
|
|
622
|
+
|
|
623
|
+
return result, response, None
|