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
zscaler/zia/firewall.py
ADDED
|
@@ -0,0 +1,1104 @@
|
|
|
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 (
|
|
22
|
+
convert_keys,
|
|
23
|
+
recursive_snake_to_camel,
|
|
24
|
+
snake_to_camel,
|
|
25
|
+
transform_common_id_fields,
|
|
26
|
+
)
|
|
27
|
+
from zscaler.zia import ZIAClient
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class FirewallPolicyAPI:
|
|
31
|
+
# Firewall filter rule keys that only require an ID to be provided.
|
|
32
|
+
reformat_params = [
|
|
33
|
+
("app_services", "appServices"),
|
|
34
|
+
("app_service_groups", "appServiceGroups"),
|
|
35
|
+
("departments", "departments"),
|
|
36
|
+
("devices", "devices"),
|
|
37
|
+
("device_groups", "deviceGroups"),
|
|
38
|
+
("dest_ip_groups", "destIpGroups"),
|
|
39
|
+
("dest_ipv6_groups", "destIpv6Groups"),
|
|
40
|
+
("groups", "groups"),
|
|
41
|
+
("labels", "labels"),
|
|
42
|
+
("locations", "locations"),
|
|
43
|
+
("location_groups", "locationGroups"),
|
|
44
|
+
("nw_application_groups", "nwApplicationGroups"),
|
|
45
|
+
("nw_service_groups", "nwServiceGroups"),
|
|
46
|
+
("src_ip_groups", "srcIpGroups"),
|
|
47
|
+
("src_ipv6_groups", "srcIpv6Groups"),
|
|
48
|
+
("time_windows", "timeWindows"),
|
|
49
|
+
("users", "users"),
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
def __init__(self, client: ZIAClient):
|
|
53
|
+
self.rest = client
|
|
54
|
+
|
|
55
|
+
def list_rules(self) -> BoxList:
|
|
56
|
+
"""
|
|
57
|
+
Returns a list of all firewall filter rules.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
:obj:`BoxList`: The list of firewall filter rules
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
>>> for rule in zia.firewall.list_rules():
|
|
64
|
+
... pprint(rule)
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
return self.rest.get("firewallFilteringRules")
|
|
68
|
+
|
|
69
|
+
def get_rule(self, rule_id: str) -> Box:
|
|
70
|
+
"""
|
|
71
|
+
Returns information for the specified firewall filter rule.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
rule_id (str): The unique identifier for the firewall filter rule.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
:obj:`Box`: The resource record for the firewall filter rule.
|
|
78
|
+
|
|
79
|
+
Examples:
|
|
80
|
+
>>> pprint(zia.firewall.get_rule('431233'))
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
return self.rest.get(f"firewallFilteringRules/{rule_id}")
|
|
84
|
+
|
|
85
|
+
def add_rule(self, name: str, action: str, **kwargs) -> Box:
|
|
86
|
+
"""
|
|
87
|
+
Adds a new firewall filter rule.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
name (str): Name of the rule, max 31 chars.
|
|
91
|
+
action (str): Action for the rule.
|
|
92
|
+
device_trust_levels (list): Device trust levels for the rule application.
|
|
93
|
+
Values: `ANY`, `UNKNOWN_DEVICETRUSTLEVEL`, `LOW_TRUST`, `MEDIUM_TRUST`,
|
|
94
|
+
`HIGH_TRUST`.
|
|
95
|
+
|
|
96
|
+
Keyword Args:
|
|
97
|
+
order (str): Rule order, defaults to the bottom.
|
|
98
|
+
rank (str): Admin rank of the rule.
|
|
99
|
+
state (str): Rule state ('ENABLED' or 'DISABLED').
|
|
100
|
+
description (str): Rule description.
|
|
101
|
+
src_ips (list): Source IPs for the rule. Accepts IP addresses or CIDR.
|
|
102
|
+
dest_addresses (list): Destination IPs for the rule. Accepts IP addresses or CIDR.
|
|
103
|
+
dest_ip_categories (list): IP address categories for the rule.
|
|
104
|
+
dest_countries (list): Destination countries for the rule.
|
|
105
|
+
enable_full_logging (bool): If True, enables full logging.
|
|
106
|
+
nw_applications (list): Network service applications for the rule.
|
|
107
|
+
app_services (list): IDs for application services for the rule.
|
|
108
|
+
app_service_groups (list): IDs for app service groups.
|
|
109
|
+
departments (list): IDs for departments the rule applies to.
|
|
110
|
+
dest_ip_groups (list): IDs for destination IP groups.
|
|
111
|
+
devices (list): IDs for devices managed by Zscaler Client Connector.
|
|
112
|
+
device_groups (list): IDs for device groups managed by Zscaler Client Connector.
|
|
113
|
+
groups (list): IDs for groups the rule applies to.
|
|
114
|
+
labels (list): IDs for labels the rule applies to.
|
|
115
|
+
locations (list): IDs for locations the rule applies to.
|
|
116
|
+
location_groups (list): IDs for location groups.
|
|
117
|
+
nw_application_groups (list): IDs for network application groups.
|
|
118
|
+
nw_services (list): IDs for network services the rule applies to.
|
|
119
|
+
nw_service_groups (list): IDs for network service groups.
|
|
120
|
+
time_windows (list): IDs for time windows the rule applies to.
|
|
121
|
+
users (list): IDs for users the rule applies to.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
:obj:`Box`: New firewall filter rule resource record.
|
|
125
|
+
|
|
126
|
+
Examples:
|
|
127
|
+
Add a rule to allow all traffic to Google DNS:
|
|
128
|
+
|
|
129
|
+
>>> zia.firewall.add_rule(rank='7', dest_addresses=['8.8.8.8', '8.8.4.4'],
|
|
130
|
+
... name='ALLOW_ANY_TO_GOOG-DNS', action='ALLOW', description='TT#1965432122')
|
|
131
|
+
|
|
132
|
+
Block traffic to Quad9 DNS for Finance Group, send ICMP error:
|
|
133
|
+
|
|
134
|
+
>>> zia.firewall.add_rule(rank='7', dest_addresses=['9.9.9.9'],
|
|
135
|
+
... name='BLOCK_GROUP-FIN_TO_Q9-DNS', action='BLOCK_ICMP', groups=['95016183'],
|
|
136
|
+
... description='TT#1965432122')
|
|
137
|
+
"""
|
|
138
|
+
# Convert enabled to API format if present
|
|
139
|
+
if "enabled" in kwargs:
|
|
140
|
+
kwargs["state"] = "ENABLED" if kwargs.pop("enabled") else "DISABLED"
|
|
141
|
+
|
|
142
|
+
payload = {
|
|
143
|
+
"name": name,
|
|
144
|
+
"action": action,
|
|
145
|
+
"order": kwargs.pop("order", len(self.list_rules())),
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# Transform ID fields in kwargs
|
|
149
|
+
transform_common_id_fields(self.reformat_params, kwargs, payload)
|
|
150
|
+
for key, value in kwargs.items():
|
|
151
|
+
if value is not None:
|
|
152
|
+
payload[snake_to_camel(key)] = value
|
|
153
|
+
|
|
154
|
+
# Convert the entire payload's keys to camelCase before sending
|
|
155
|
+
camel_payload = recursive_snake_to_camel(payload)
|
|
156
|
+
for key, value in kwargs.items():
|
|
157
|
+
if value is not None:
|
|
158
|
+
camel_payload[snake_to_camel(key)] = value
|
|
159
|
+
|
|
160
|
+
# Send POST request to create the rule
|
|
161
|
+
response = self.rest.post("firewallFilteringRules", json=payload)
|
|
162
|
+
if isinstance(response, Response):
|
|
163
|
+
status_code = response.status_code
|
|
164
|
+
if status_code != 200:
|
|
165
|
+
raise Exception(
|
|
166
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
167
|
+
)
|
|
168
|
+
return response
|
|
169
|
+
|
|
170
|
+
def update_rule(self, rule_id: str, **kwargs) -> Box:
|
|
171
|
+
"""
|
|
172
|
+
Updates an existing firewall filter rule.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
rule_id (str): The unique ID for the rule that is being updated.
|
|
176
|
+
**kwargs: Optional keyword args.
|
|
177
|
+
|
|
178
|
+
Keyword Args:
|
|
179
|
+
order (str): The order of the rule, defaults to adding rule to bottom of list.
|
|
180
|
+
rank (str): The admin rank of the rule.
|
|
181
|
+
state (str): The rule state. Accepted values are 'ENABLED' or 'DISABLED'.
|
|
182
|
+
description (str): Additional information about the rule
|
|
183
|
+
src_ips (list): The source IPs that this rule applies to. Individual IP addresses or CIDR ranges accepted.
|
|
184
|
+
dest_addresses (list): The destination IP addresses that this rule applies to. Individual IP addresses or
|
|
185
|
+
CIDR ranges accepted.
|
|
186
|
+
dest_ip_categories (list): The IP address categories that this rule applies to.
|
|
187
|
+
dest_countries (list): The destination countries that this rule applies to.
|
|
188
|
+
enable_full_logging (bool): Enables full logging if True.
|
|
189
|
+
nw_applications (list): The network service applications that this rule applies to.
|
|
190
|
+
app_services (list): The IDs for the application services that this rule applies to.
|
|
191
|
+
app_service_groups (list): The IDs for the application service groups that this rule applies to.
|
|
192
|
+
departments (list): The IDs for the departments that this rule applies to.
|
|
193
|
+
dest_ip_groups (list): The IDs for the destination IP groups that this rule applies to.
|
|
194
|
+
groups (list): The IDs for the groups that this rule applies to.
|
|
195
|
+
labels (list): The IDs for the labels that this rule applies to.
|
|
196
|
+
locations (list): The IDs for the locations that this rule applies to.
|
|
197
|
+
location_groups (list): The IDs for the location groups that this rule applies to.
|
|
198
|
+
nw_application_groups (list): The IDs for the network application groups that this rule applies to.
|
|
199
|
+
nw_services (list): The IDs for the network services that this rule applies to.
|
|
200
|
+
nw_service_groups (list): The IDs for the network service groups that this rule applies to.
|
|
201
|
+
time_windows (list): The IDs for the time windows that this rule applies to.
|
|
202
|
+
users (list): The IDs for the users that this rule applies to.
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
:obj:`Box`: The updated firewall filter rule resource record.
|
|
206
|
+
|
|
207
|
+
Examples:
|
|
208
|
+
Update the destination IP addresses for a rule:
|
|
209
|
+
|
|
210
|
+
>>> zia.firewall.update_rule('976598',
|
|
211
|
+
... dest_addresses=['1.1.1.1'],
|
|
212
|
+
... description="TT#1965232865")
|
|
213
|
+
|
|
214
|
+
Update a rule to enable full logging:
|
|
215
|
+
|
|
216
|
+
>>> zia.firewall.update_rule('976597',
|
|
217
|
+
... enable_full_logging=True,
|
|
218
|
+
... description="TT#1965232866")
|
|
219
|
+
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
# Set payload to value of existing record and convert nested dict keys.
|
|
223
|
+
payload = convert_keys(self.get_rule(rule_id))
|
|
224
|
+
|
|
225
|
+
# Convert enabled to API format if present in kwargs
|
|
226
|
+
if "enabled" in kwargs:
|
|
227
|
+
kwargs["state"] = "ENABLED" if kwargs.pop("enabled") else "DISABLED"
|
|
228
|
+
|
|
229
|
+
# Transform ID fields in kwargs
|
|
230
|
+
transform_common_id_fields(self.reformat_params, kwargs, payload)
|
|
231
|
+
|
|
232
|
+
# Add remaining optional parameters to payload
|
|
233
|
+
for key, value in kwargs.items():
|
|
234
|
+
payload[snake_to_camel(key)] = value
|
|
235
|
+
|
|
236
|
+
response = self.rest.put(f"firewallFilteringRules/{rule_id}", json=payload)
|
|
237
|
+
if isinstance(response, Response) and not response.ok:
|
|
238
|
+
# Handle error response
|
|
239
|
+
raise Exception(
|
|
240
|
+
f"API call failed with status {response.status_code}: {response.json()}"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# Return the updated object
|
|
244
|
+
return self.get_rule(rule_id)
|
|
245
|
+
|
|
246
|
+
def delete_rule(self, rule_id: str) -> int:
|
|
247
|
+
"""
|
|
248
|
+
Deletes the specified firewall filter rule.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
rule_id (str): The unique identifier for the firewall filter rule.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
:obj:`int`: The status code for the operation.
|
|
255
|
+
|
|
256
|
+
Examples:
|
|
257
|
+
>>> zia.firewall.delete_rule('278454')
|
|
258
|
+
|
|
259
|
+
"""
|
|
260
|
+
return self.rest.delete(f"firewallFilteringRules/{rule_id}").status_code
|
|
261
|
+
|
|
262
|
+
def list_ip_destination_groups(self, exclude_type: str = None) -> BoxList:
|
|
263
|
+
"""
|
|
264
|
+
Returns a list of IP Destination Groups.
|
|
265
|
+
|
|
266
|
+
Args:
|
|
267
|
+
exclude_type (str): Exclude all groups that match the specified IP destination group's type.
|
|
268
|
+
Accepted values are: `DSTN_IP`, `DSTN_FQDN`, `DSTN_DOMAIN` and `DSTN_OTHER`.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
:obj:`BoxList`: List of IP Destination Group records.
|
|
272
|
+
|
|
273
|
+
Examples:
|
|
274
|
+
>>> for group in zia.firewall.list_ip_destination_groups():
|
|
275
|
+
... pprint(group)
|
|
276
|
+
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
payload = {"excludeType": exclude_type}
|
|
280
|
+
|
|
281
|
+
return self.rest.get("ipDestinationGroups", params=payload)
|
|
282
|
+
|
|
283
|
+
def get_ip_destination_group(self, group_id: str) -> Box:
|
|
284
|
+
"""
|
|
285
|
+
Returns information on the specified IP Destination Group.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
group_id (str): The unique ID of the IP Destination Group.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
:obj:`Box`: The IP Destination Group resource record.
|
|
292
|
+
|
|
293
|
+
Examples:
|
|
294
|
+
>>> pprint(zia.firewall.get_ip_destination_group('287342'))
|
|
295
|
+
|
|
296
|
+
"""
|
|
297
|
+
return self.rest.get(f"ipDestinationGroups/{group_id}")
|
|
298
|
+
|
|
299
|
+
def delete_ip_destination_group(self, group_id: str) -> int:
|
|
300
|
+
"""
|
|
301
|
+
Deletes the specified IP Destination Group.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
group_id (str): The unique ID of the IP Destination Group.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
:obj:`int`: The status code of the operation.
|
|
308
|
+
|
|
309
|
+
Examples:
|
|
310
|
+
>>> zia.firewall.delete_ip_destination_group('287342')
|
|
311
|
+
|
|
312
|
+
"""
|
|
313
|
+
return self.rest.delete(f"ipDestinationGroups/{group_id}").status_code
|
|
314
|
+
|
|
315
|
+
def add_ip_destination_group(self, name: str, **kwargs) -> Box:
|
|
316
|
+
"""
|
|
317
|
+
Adds a new IP Destination Group.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
name (str): The name of the IP Destination Group.
|
|
321
|
+
**kwargs: Optional keyword args.
|
|
322
|
+
|
|
323
|
+
Keyword Args:
|
|
324
|
+
type (str): Destination IP group type. Allowed values are DSTN_IP and DSTN_FQDN.
|
|
325
|
+
addresses (list): Destination IP addresses or FQDNs within the group.
|
|
326
|
+
description (str): Additional information about the destination IP group.
|
|
327
|
+
ip_categories (list): Destination IP address URL categories.
|
|
328
|
+
countries (list): Destination IP address counties.
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
:obj:`Box`: The newly created IP Destination Group resource record.
|
|
332
|
+
|
|
333
|
+
Examples:
|
|
334
|
+
Add a Destination IP Group with IP addresses:
|
|
335
|
+
|
|
336
|
+
>>> zia.firewall.add_ip_destination_group(name='Destination Group - IP',
|
|
337
|
+
... addresses=['203.0.113.0/25', '203.0.113.131'],
|
|
338
|
+
... type='DSTN_IP')
|
|
339
|
+
|
|
340
|
+
Add a Destination IP Group with FQDN:
|
|
341
|
+
|
|
342
|
+
>>> zia.firewall.add_ip_destination_group(name='Destination Group - FQDN',
|
|
343
|
+
... description='Covers domains for Example Inc.',
|
|
344
|
+
... addresses=['example.com', 'example.edu'],
|
|
345
|
+
... type='DSTN_FQDN')
|
|
346
|
+
|
|
347
|
+
Add a Destionation IP Group for the US:
|
|
348
|
+
|
|
349
|
+
>>> zia.firewall.add_ip_destination_group(name='Destination Group - US',
|
|
350
|
+
... description='Covers the US',
|
|
351
|
+
... countries=['COUNTRY_US'])
|
|
352
|
+
|
|
353
|
+
"""
|
|
354
|
+
|
|
355
|
+
payload = {"name": name}
|
|
356
|
+
|
|
357
|
+
# Add optional parameters to payload
|
|
358
|
+
for key, value in kwargs.items():
|
|
359
|
+
payload[snake_to_camel(key)] = value
|
|
360
|
+
|
|
361
|
+
return self.rest.post("ipDestinationGroups", json=payload)
|
|
362
|
+
|
|
363
|
+
def update_ip_destination_group(self, group_id: str, **kwargs) -> Box:
|
|
364
|
+
"""
|
|
365
|
+
Updates the specified IP Destination Group.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
group_id (str): The unique ID of the IP Destination Group.
|
|
369
|
+
**kwargs: Optional keyword args.
|
|
370
|
+
|
|
371
|
+
Keyword Args:
|
|
372
|
+
name (str): The name of the IP Destination Group.
|
|
373
|
+
addresses (list): Destination IP addresses or FQDNs within the group.
|
|
374
|
+
description (str): Additional information about the IP Destination Group.
|
|
375
|
+
ip_categories (list): Destination IP address URL categories.
|
|
376
|
+
countries (list): Destination IP address countries.
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
:obj:`Box`: The updated IP Destination Group resource record.
|
|
380
|
+
|
|
381
|
+
Examples:
|
|
382
|
+
Update the name of an IP Destination Group:
|
|
383
|
+
|
|
384
|
+
>>> zia.firewall.update_ip_destination_group('9032667',
|
|
385
|
+
... name="Updated IP Destination Group")
|
|
386
|
+
|
|
387
|
+
Update the description and FQDNs for an IP Destination Group:
|
|
388
|
+
|
|
389
|
+
>>> zia.firewall.update_ip_destination_group('9032668',
|
|
390
|
+
... description="Tech News",
|
|
391
|
+
... addresses=['arstechnica.com', 'slashdot.org'])
|
|
392
|
+
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
# Set payload to value of existing record
|
|
396
|
+
payload = {
|
|
397
|
+
snake_to_camel(k): v
|
|
398
|
+
for k, v in self.get_ip_destination_group(group_id).items()
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
# Update payload
|
|
402
|
+
for key, value in kwargs.items():
|
|
403
|
+
payload[snake_to_camel(key)] = value
|
|
404
|
+
|
|
405
|
+
return self.rest.put(f"ipDestinationGroups/{group_id}", json=payload)
|
|
406
|
+
|
|
407
|
+
def list_ip_source_groups(self, search: str = None) -> BoxList:
|
|
408
|
+
"""
|
|
409
|
+
Returns a list of IP Source Groups.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
search (str): The search string used to match against a group's name or description attributes.
|
|
413
|
+
|
|
414
|
+
Returns:
|
|
415
|
+
:obj:`BoxList`: List of IP Source Group records.
|
|
416
|
+
|
|
417
|
+
Examples:
|
|
418
|
+
List all IP Source Groups:
|
|
419
|
+
|
|
420
|
+
>>> for group in zia.firewall.list_ip_source_groups():
|
|
421
|
+
... pprint(group)
|
|
422
|
+
|
|
423
|
+
Use search parameter to find IP Source Groups with `fiji` in the name:
|
|
424
|
+
|
|
425
|
+
>>> for group in zia.firewall.list_ip_source_groups('fiji'):
|
|
426
|
+
... pprint(group)
|
|
427
|
+
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
payload = {"search": search}
|
|
431
|
+
|
|
432
|
+
return self.rest.get("ipSourceGroups", json=payload)
|
|
433
|
+
|
|
434
|
+
def get_ip_source_group(self, group_id: str) -> Box:
|
|
435
|
+
"""
|
|
436
|
+
Returns information for the specified IP Source Group.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
group_id (str): The unique ID of the IP Source Group.
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
:obj:`Box`: The IP Source Group resource record.
|
|
443
|
+
|
|
444
|
+
Examples:
|
|
445
|
+
>>> pprint(zia.firewall.get_ip_source_group('762398')
|
|
446
|
+
|
|
447
|
+
"""
|
|
448
|
+
return self.rest.get(f"ipSourceGroups/{group_id}")
|
|
449
|
+
|
|
450
|
+
def delete_ip_source_group(self, group_id: str) -> int:
|
|
451
|
+
"""
|
|
452
|
+
Deletes an IP Source Group.
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
group_id (str): The unique ID of the IP Source Group to be deleted.
|
|
456
|
+
|
|
457
|
+
Returns:
|
|
458
|
+
:obj:`int`: The status code for the operation.
|
|
459
|
+
|
|
460
|
+
Examples:
|
|
461
|
+
>>> zia.firewall.delete_ip_source_group('762398')
|
|
462
|
+
|
|
463
|
+
"""
|
|
464
|
+
return self.rest.delete(f"ipSourceGroups/{group_id}").status_code
|
|
465
|
+
|
|
466
|
+
def add_ip_source_group(
|
|
467
|
+
self, name: str, ip_addresses: list, description: str = None
|
|
468
|
+
) -> Box:
|
|
469
|
+
"""
|
|
470
|
+
Adds a new IP Source Group.
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
name (str): The name of the IP Source Group.
|
|
474
|
+
ip_addresses (str): The list of IP addresses for the IP Source Group.
|
|
475
|
+
description (str): Additional information for the IP Source Group.
|
|
476
|
+
|
|
477
|
+
Returns:
|
|
478
|
+
:obj:`Box`: The new IP Source Group resource record.
|
|
479
|
+
|
|
480
|
+
Examples:
|
|
481
|
+
Add a new IP Source Group:
|
|
482
|
+
|
|
483
|
+
>>> zia.firewall.add_ip_source_group(name='My IP Source Group',
|
|
484
|
+
... ip_addresses=['198.51.100.0/24', '192.0.2.1'],
|
|
485
|
+
... description='Contains the IP addresses for the local network.')
|
|
486
|
+
|
|
487
|
+
"""
|
|
488
|
+
|
|
489
|
+
payload = {
|
|
490
|
+
"name": name,
|
|
491
|
+
"ipAddresses": ip_addresses,
|
|
492
|
+
"description": description,
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
return self.rest.post("ipSourceGroups", json=payload)
|
|
496
|
+
|
|
497
|
+
def update_ip_source_group(self, group_id: str, **kwargs) -> Box:
|
|
498
|
+
"""
|
|
499
|
+
Update an IP Source Group.
|
|
500
|
+
|
|
501
|
+
This method supports updating individual fields in the IP Source Group resource record.
|
|
502
|
+
|
|
503
|
+
Args:
|
|
504
|
+
group_id (str): The unique ID for the IP Source Group to update.
|
|
505
|
+
**kwargs: Optional keyword args.
|
|
506
|
+
|
|
507
|
+
Keyword Args:
|
|
508
|
+
name (str): The name of the IP Source Group.
|
|
509
|
+
ip_addresses (list): The list of IP addresses for the IP Source Group.
|
|
510
|
+
description (str): Additional information for the IP Source Group.
|
|
511
|
+
|
|
512
|
+
Returns:
|
|
513
|
+
:obj:`Box`: The updated IP Source Group resource record.
|
|
514
|
+
|
|
515
|
+
Examples:
|
|
516
|
+
Update the name of an IP Source Group:
|
|
517
|
+
|
|
518
|
+
>>> zia.firewall.update_ip_source_group('9032674',
|
|
519
|
+
... name='Updated Name')
|
|
520
|
+
|
|
521
|
+
Update the description and IP addresses of an IP Source Group:
|
|
522
|
+
|
|
523
|
+
>>> zia.firewall.update_ip_source_group('9032674',
|
|
524
|
+
... description='Local subnets, updated on 3 JUL 21'
|
|
525
|
+
... ip_addresses=['192.0.2.0/29', '192.0.2.8/29', '192.0.2.128/25'])
|
|
526
|
+
|
|
527
|
+
"""
|
|
528
|
+
|
|
529
|
+
# Set payload to value of existing record
|
|
530
|
+
payload = {
|
|
531
|
+
snake_to_camel(k): v for k, v in self.get_ip_source_group(group_id).items()
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
# Update payload
|
|
535
|
+
for key, value in kwargs.items():
|
|
536
|
+
payload[snake_to_camel(key)] = value
|
|
537
|
+
|
|
538
|
+
return self.rest.put(f"ipSourceGroups/{group_id}", json=payload)
|
|
539
|
+
|
|
540
|
+
def list_network_app_groups(self, search: str = None) -> BoxList:
|
|
541
|
+
"""
|
|
542
|
+
Returns a list of all Network Application Groups.
|
|
543
|
+
|
|
544
|
+
Returns:
|
|
545
|
+
:obj:`BoxList`: The list of Network Application Group resource records.
|
|
546
|
+
|
|
547
|
+
Examples:
|
|
548
|
+
>>> for group in zia.firewall.list_network_app_groups():
|
|
549
|
+
... pprint(group)
|
|
550
|
+
|
|
551
|
+
"""
|
|
552
|
+
payload = {"search": search}
|
|
553
|
+
list = self.rest.get(path="/networkApplicationGroups", params=payload)
|
|
554
|
+
if isinstance(list, Response):
|
|
555
|
+
return None
|
|
556
|
+
return list
|
|
557
|
+
|
|
558
|
+
# payload = {"search": search}
|
|
559
|
+
# return self.rest.get("networkApplicationGroups", params=payload)
|
|
560
|
+
|
|
561
|
+
def get_network_app_group(self, group_id: str) -> Box:
|
|
562
|
+
"""
|
|
563
|
+
Returns information for the specified Network Application Group.
|
|
564
|
+
|
|
565
|
+
Args:
|
|
566
|
+
group_id (str):
|
|
567
|
+
The unique ID for the Network Application Group.
|
|
568
|
+
|
|
569
|
+
Returns:
|
|
570
|
+
:obj:`Box`: The Network Application Group resource record.
|
|
571
|
+
"""
|
|
572
|
+
response = self.rest.get(f"networkApplicationGroups/{group_id}")
|
|
573
|
+
|
|
574
|
+
# If 'response' is a Box, it should contain the response data directly
|
|
575
|
+
# If 'response' is an HTTP response, it should have a 'status_code' attribute
|
|
576
|
+
if hasattr(response, "status_code"):
|
|
577
|
+
# Check if the response is successful and the content is not empty
|
|
578
|
+
if response.status_code == 200 and response.content:
|
|
579
|
+
# Convert to Box for consistent return type
|
|
580
|
+
return Box(response.json())
|
|
581
|
+
else:
|
|
582
|
+
# Handle non-200 responses
|
|
583
|
+
response.raise_for_status()
|
|
584
|
+
else:
|
|
585
|
+
# Assume 'response' is a Box and contains the desired data
|
|
586
|
+
if "ok" in response and response.ok:
|
|
587
|
+
# 'response' is a Box with the expected data
|
|
588
|
+
return response
|
|
589
|
+
else:
|
|
590
|
+
# Handle cases where the response Box does not contain the expected data
|
|
591
|
+
# For example, you might want to check for an 'error' or 'message' field
|
|
592
|
+
# and raise an exception or handle the situation as needed
|
|
593
|
+
# Example: raise ValueError("Failed to retrieve the network application group.")
|
|
594
|
+
return (
|
|
595
|
+
Box()
|
|
596
|
+
) # An empty Box indicates no data was found or an error occurred.
|
|
597
|
+
|
|
598
|
+
def delete_network_app_group(self, group_id: str) -> int:
|
|
599
|
+
"""
|
|
600
|
+
Deletes the specified Network Application Group.
|
|
601
|
+
|
|
602
|
+
Args:
|
|
603
|
+
group_id (str): The unique identifier for the Network Application Group.
|
|
604
|
+
|
|
605
|
+
Returns:
|
|
606
|
+
:obj:`int`: The response code for the operation.
|
|
607
|
+
|
|
608
|
+
Examples:
|
|
609
|
+
>>> zia.firewall.delete_network_app_group('762398')
|
|
610
|
+
|
|
611
|
+
"""
|
|
612
|
+
return self.rest.delete(f"networkApplicationGroups/{group_id}").status_code
|
|
613
|
+
|
|
614
|
+
def add_network_app_group(
|
|
615
|
+
self, name: str, network_applications: list, description: str = None
|
|
616
|
+
) -> Box:
|
|
617
|
+
"""
|
|
618
|
+
Adds a new Network Application Group.
|
|
619
|
+
|
|
620
|
+
Args:
|
|
621
|
+
name (str): The name of the Network Application Group.
|
|
622
|
+
description (str): Additional information about the Network Application Group.
|
|
623
|
+
network_applications (list): A list of Application IDs to add to the group.
|
|
624
|
+
|
|
625
|
+
Returns:
|
|
626
|
+
:obj:`Box`: The newly created Network Application Group resource record.
|
|
627
|
+
|
|
628
|
+
Examples:
|
|
629
|
+
Add a new Network Application Group:
|
|
630
|
+
|
|
631
|
+
>>> zia.firewall.add_network_app_group(name='New Network Application Group',
|
|
632
|
+
... network_applications=['SALESFORCE', 'GOOGLEANALYTICS', 'OFFICE365'],
|
|
633
|
+
... description='Additional information about the Network Application Group.')
|
|
634
|
+
|
|
635
|
+
"""
|
|
636
|
+
|
|
637
|
+
payload = {
|
|
638
|
+
"name": name,
|
|
639
|
+
"networkApplications": network_applications,
|
|
640
|
+
"description": description,
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
response = self.rest.post("networkApplicationGroups", json=payload)
|
|
644
|
+
if isinstance(response, Response):
|
|
645
|
+
# this is only true when the creation failed (status code is not 2xx)
|
|
646
|
+
status_code = response.status_code
|
|
647
|
+
# Handle error response
|
|
648
|
+
raise Exception(
|
|
649
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
650
|
+
)
|
|
651
|
+
return response
|
|
652
|
+
|
|
653
|
+
# return self.rest.post("networkApplicationGroups", json=payload)
|
|
654
|
+
|
|
655
|
+
def update_network_app_group(self, group_id: str, **kwargs) -> Box:
|
|
656
|
+
"""
|
|
657
|
+
Update an Network Application Group.
|
|
658
|
+
|
|
659
|
+
This method supports updating individual fields in the Network Application Group resource record.
|
|
660
|
+
|
|
661
|
+
Args:
|
|
662
|
+
group_id (str): The unique ID for the Network Application Group to update.
|
|
663
|
+
**kwargs: Optional keyword args.
|
|
664
|
+
|
|
665
|
+
Keyword Args:
|
|
666
|
+
name (str): The name of the Network Application Group.
|
|
667
|
+
network_applications (list): The list of applications for the Network Application Group.
|
|
668
|
+
description (str): Additional information for the Network Application Group.
|
|
669
|
+
|
|
670
|
+
Returns:
|
|
671
|
+
:obj:`Box`: The updated Network Application Group resource record.
|
|
672
|
+
|
|
673
|
+
Examples:
|
|
674
|
+
Update the name of an Network Application Group:
|
|
675
|
+
|
|
676
|
+
>>> zia.firewall.update_network_app_group('9032674',
|
|
677
|
+
... name='Updated Network Application Group Name')
|
|
678
|
+
|
|
679
|
+
Update the description and applications for a Network Application Group:
|
|
680
|
+
|
|
681
|
+
>>> zia.firewall.update_network_app_group('9032674',
|
|
682
|
+
... description='Network Application Group, updated on May 27, 2023'
|
|
683
|
+
... network_applications=['SALESFORCE', 'GOOGLEANALYTICS', 'OFFICE365'])
|
|
684
|
+
|
|
685
|
+
"""
|
|
686
|
+
|
|
687
|
+
# Set payload to value of existing record
|
|
688
|
+
payload = {
|
|
689
|
+
snake_to_camel(k): v
|
|
690
|
+
for k, v in self.get_network_app_group(group_id).items()
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
# Update payload
|
|
694
|
+
for key, value in kwargs.items():
|
|
695
|
+
payload[snake_to_camel(key)] = value
|
|
696
|
+
|
|
697
|
+
resp = self.rest.put(
|
|
698
|
+
f"networkApplicationGroups/{group_id}", json=payload
|
|
699
|
+
).status_code
|
|
700
|
+
|
|
701
|
+
# Return the object if it was updated successfully
|
|
702
|
+
if not isinstance(resp, Response):
|
|
703
|
+
return self.get_network_app_group(group_id)
|
|
704
|
+
|
|
705
|
+
def list_network_apps(self, search: str = None) -> BoxList:
|
|
706
|
+
"""
|
|
707
|
+
Returns a list of all predefined Network Applications.
|
|
708
|
+
|
|
709
|
+
Args:
|
|
710
|
+
search (str): The search string used to match against a network application's description attribute.
|
|
711
|
+
|
|
712
|
+
Returns:
|
|
713
|
+
:obj:`BoxList`: The list of Network Application resource records.
|
|
714
|
+
|
|
715
|
+
Examples:
|
|
716
|
+
>>> for app in zia.firewall.list_network_apps():
|
|
717
|
+
... pprint(app)
|
|
718
|
+
|
|
719
|
+
"""
|
|
720
|
+
payload = {"search": search}
|
|
721
|
+
return self.rest.get("networkApplications", params=payload)
|
|
722
|
+
|
|
723
|
+
def get_network_app(self, app_id: str) -> Box:
|
|
724
|
+
"""
|
|
725
|
+
Returns information for the specified Network Application.
|
|
726
|
+
|
|
727
|
+
Args:
|
|
728
|
+
app_id (str): The unique ID for the Network Application.
|
|
729
|
+
|
|
730
|
+
Returns:
|
|
731
|
+
:obj:`Box`: The Network Application resource record.
|
|
732
|
+
|
|
733
|
+
Examples:
|
|
734
|
+
>>> pprint(zia.firewall.get_network_app('762398'))
|
|
735
|
+
|
|
736
|
+
"""
|
|
737
|
+
return self.rest.get(f"networkApplications/{app_id}")
|
|
738
|
+
|
|
739
|
+
def list_network_svc_groups(self, search: str = None) -> BoxList:
|
|
740
|
+
"""
|
|
741
|
+
Returns a list of Network Service Groups.
|
|
742
|
+
|
|
743
|
+
Args:
|
|
744
|
+
search (str): The search string used to match against a group's name or description attributes.
|
|
745
|
+
|
|
746
|
+
Returns:
|
|
747
|
+
:obj:`BoxList`: List of Network Service Group resource records.
|
|
748
|
+
|
|
749
|
+
Examples:
|
|
750
|
+
>>> for group in zia.firewall.list_network_svc_groups():
|
|
751
|
+
... pprint(group)
|
|
752
|
+
|
|
753
|
+
"""
|
|
754
|
+
|
|
755
|
+
payload = {}
|
|
756
|
+
if search:
|
|
757
|
+
payload["search"] = search
|
|
758
|
+
return self.rest.get("networkServiceGroups", params=payload)
|
|
759
|
+
|
|
760
|
+
def get_network_svc_group(self, group_id: str) -> Box:
|
|
761
|
+
"""
|
|
762
|
+
Returns information for the specified Network Service Group.
|
|
763
|
+
|
|
764
|
+
Args:
|
|
765
|
+
group_id (str): The unique ID for the Network Service Group.
|
|
766
|
+
|
|
767
|
+
Returns:
|
|
768
|
+
:obj:`Box`: The Network Service Group resource record.
|
|
769
|
+
|
|
770
|
+
Examples:
|
|
771
|
+
>>> pprint(zia.firewall.get_network_svc_group('762398'))
|
|
772
|
+
|
|
773
|
+
"""
|
|
774
|
+
return self.rest.get(f"networkServiceGroups/{group_id}")
|
|
775
|
+
|
|
776
|
+
def delete_network_svc_group(self, group_id: str) -> int:
|
|
777
|
+
"""
|
|
778
|
+
Deletes the specified Network Service Group.
|
|
779
|
+
|
|
780
|
+
Args:
|
|
781
|
+
group_id (str): The unique identifier for the Network Service Group.
|
|
782
|
+
|
|
783
|
+
Returns:
|
|
784
|
+
:obj:`int`: The response code for the operation.
|
|
785
|
+
|
|
786
|
+
Examples:
|
|
787
|
+
>>> zia.firewall.delete_network_svc_group('762398')
|
|
788
|
+
|
|
789
|
+
"""
|
|
790
|
+
return self.rest.delete(f"networkServiceGroups/{group_id}").status_code
|
|
791
|
+
|
|
792
|
+
def add_network_svc_group(
|
|
793
|
+
self, name: str, service_ids: list, description: str = None
|
|
794
|
+
) -> Box:
|
|
795
|
+
"""
|
|
796
|
+
Adds a new Network Service Group.
|
|
797
|
+
|
|
798
|
+
Args:
|
|
799
|
+
name (str): The name of the Network Service Group.
|
|
800
|
+
service_ids (list): A list of Network Service IDs to add to the group.
|
|
801
|
+
description (str): Additional information about the Network Service Group.
|
|
802
|
+
|
|
803
|
+
Returns:
|
|
804
|
+
:obj:`Box`: The newly created Network Service Group resource record.
|
|
805
|
+
|
|
806
|
+
Examples:
|
|
807
|
+
Add a new Network Service Group:
|
|
808
|
+
|
|
809
|
+
>>> zia.firewall.add_network_svc_group(name='New Network Service Group',
|
|
810
|
+
... service_ids=['159143', '159144', '159145'],
|
|
811
|
+
... description='Group for the new Network Service.')
|
|
812
|
+
|
|
813
|
+
"""
|
|
814
|
+
|
|
815
|
+
payload = {"name": name, "services": [], "description": description}
|
|
816
|
+
|
|
817
|
+
for service_id in service_ids:
|
|
818
|
+
payload["services"].append({"id": service_id})
|
|
819
|
+
|
|
820
|
+
return self.rest.post("networkServiceGroups", json=payload)
|
|
821
|
+
|
|
822
|
+
def update_network_svc_group(self, group_id: str, **kwargs) -> Box:
|
|
823
|
+
"""
|
|
824
|
+
Update a Network Service Group.
|
|
825
|
+
|
|
826
|
+
Args:
|
|
827
|
+
group_id (str): The unique ID of the Network Service Group.
|
|
828
|
+
**kwargs: Optional keyword args.
|
|
829
|
+
|
|
830
|
+
Keyword Args:
|
|
831
|
+
name (str): The name of the Network Service Group.
|
|
832
|
+
service_ids (list): A list of Network Service IDs to add to the group.
|
|
833
|
+
description (str): Additional information about the Network Service Group.
|
|
834
|
+
|
|
835
|
+
Returns:
|
|
836
|
+
:obj:`Box`: The updated Network Service Group resource record.
|
|
837
|
+
|
|
838
|
+
Examples:
|
|
839
|
+
Update the name Network Service Group:
|
|
840
|
+
|
|
841
|
+
>>> zia.firewall.update_network_svc_group(name='Update Network Service Group',
|
|
842
|
+
... service_ids=['159143', '159144', '159145'],
|
|
843
|
+
... description='Group for the new Network Service.')
|
|
844
|
+
|
|
845
|
+
"""
|
|
846
|
+
|
|
847
|
+
# Set payload to value of existing record
|
|
848
|
+
payload = {
|
|
849
|
+
snake_to_camel(k): v
|
|
850
|
+
for k, v in self.get_network_svc_group(group_id).items()
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
# Update payload
|
|
854
|
+
for key, value in kwargs.items():
|
|
855
|
+
payload[snake_to_camel(key)] = value
|
|
856
|
+
|
|
857
|
+
# return self.rest.put(f"networkServiceGroups/{group_id}", json=payload)
|
|
858
|
+
|
|
859
|
+
resp = self.rest.put(
|
|
860
|
+
f"networkServiceGroups/{group_id}", json=payload
|
|
861
|
+
).status_code
|
|
862
|
+
|
|
863
|
+
# Return the object if it was updated successfully
|
|
864
|
+
if not isinstance(resp, Response):
|
|
865
|
+
return self.get_network_svc_group(group_id)
|
|
866
|
+
|
|
867
|
+
def list_network_services(
|
|
868
|
+
self, search: str = None, protocol: str = None
|
|
869
|
+
) -> BoxList:
|
|
870
|
+
"""
|
|
871
|
+
Returns a list of all Network Services.
|
|
872
|
+
|
|
873
|
+
The search parameters find matching values within the "name" or "description" attributes.
|
|
874
|
+
|
|
875
|
+
Args:
|
|
876
|
+
search (str): The search string used to match against a service's name or description attributes.
|
|
877
|
+
protocol (str): Filter based on the network service protocol. Accepted values are `ICMP`, `TCP`, `UDP`,
|
|
878
|
+
`GRE`, `ESP` and `OTHER`.
|
|
879
|
+
|
|
880
|
+
Returns:
|
|
881
|
+
:obj:`BoxList`: The list of Network Service resource records.
|
|
882
|
+
|
|
883
|
+
Examples:
|
|
884
|
+
>>> for service in zia.firewall.list_network_services():
|
|
885
|
+
... pprint(service)
|
|
886
|
+
|
|
887
|
+
"""
|
|
888
|
+
payload = {"search": search, "protocol": protocol}
|
|
889
|
+
return self.rest.get("networkServices", params=payload)
|
|
890
|
+
|
|
891
|
+
def get_network_service(self, service_id: str) -> Box:
|
|
892
|
+
"""
|
|
893
|
+
Returns information for the specified Network Service.
|
|
894
|
+
|
|
895
|
+
Args:
|
|
896
|
+
service_id (str): The unique ID for the Network Service.
|
|
897
|
+
|
|
898
|
+
Returns:
|
|
899
|
+
:obj:`Box`: The Network Service resource record.
|
|
900
|
+
|
|
901
|
+
Examples:
|
|
902
|
+
>>> pprint(zia.firewall.get_network_service('762398'))
|
|
903
|
+
|
|
904
|
+
"""
|
|
905
|
+
return self.rest.get(f"networkServices/{service_id}")
|
|
906
|
+
|
|
907
|
+
def delete_network_service(self, service_id: str) -> int:
|
|
908
|
+
"""
|
|
909
|
+
Deletes the specified Network Service.
|
|
910
|
+
|
|
911
|
+
Args:
|
|
912
|
+
service_id (str): The unique ID for the Network Service.
|
|
913
|
+
|
|
914
|
+
Returns:
|
|
915
|
+
:obj:`int`: The status code for the operation.
|
|
916
|
+
|
|
917
|
+
Examples:
|
|
918
|
+
>>> zia.firewall.delete_network_service('762398')
|
|
919
|
+
|
|
920
|
+
"""
|
|
921
|
+
return self.rest.delete(f"networkServices/{service_id}").status_code
|
|
922
|
+
|
|
923
|
+
def add_network_service(self, name: str, ports: list = None, **kwargs) -> Box:
|
|
924
|
+
"""
|
|
925
|
+
Adds a new Network Service.
|
|
926
|
+
|
|
927
|
+
Args:
|
|
928
|
+
name: The name of the Network Service
|
|
929
|
+
ports (list):
|
|
930
|
+
A list of port protocol tuples. Tuples must follow the convention `src/dest`, `protocol`,
|
|
931
|
+
`start port`, `end port`. If this is a single port and not a port range then `end port` can be omitted.
|
|
932
|
+
E.g.
|
|
933
|
+
|
|
934
|
+
.. code-block:: python
|
|
935
|
+
|
|
936
|
+
('src', 'tcp', '49152', '65535'),
|
|
937
|
+
('dest', 'tcp', '22),
|
|
938
|
+
('dest', 'tcp', '9010', '9012'),
|
|
939
|
+
('dest', 'udp', '9010', '9012')
|
|
940
|
+
|
|
941
|
+
**kwargs: Optional keyword args.
|
|
942
|
+
|
|
943
|
+
Keyword Args:
|
|
944
|
+
description (str): Additional information on the Network Service.
|
|
945
|
+
|
|
946
|
+
Returns:
|
|
947
|
+
:obj:`Box`: The newly created Network Service resource record.
|
|
948
|
+
|
|
949
|
+
Examples:
|
|
950
|
+
Add Network Service for Microsoft Exchange:
|
|
951
|
+
|
|
952
|
+
>>> zia.firewall.add_network_service('MS LDAP',
|
|
953
|
+
... description='Covers all ports used by MS LDAP',
|
|
954
|
+
... ports=[
|
|
955
|
+
... ('dest', 'tcp', '389'),
|
|
956
|
+
... ('dest', 'udp', '389'),
|
|
957
|
+
... ('dest', 'tcp', '636'),
|
|
958
|
+
... ('dest', 'tcp', '3268', '3269')])
|
|
959
|
+
|
|
960
|
+
Add Network Service designed to match inbound SSH traffic:
|
|
961
|
+
|
|
962
|
+
>>> zia.firewall.add_network_service('Inbound SSH',
|
|
963
|
+
... description='Inbound SSH',
|
|
964
|
+
... ports=[
|
|
965
|
+
... ('src', 'tcp', '22'),
|
|
966
|
+
... ('dest', 'tcp', '1024', '65535')])
|
|
967
|
+
|
|
968
|
+
"""
|
|
969
|
+
|
|
970
|
+
payload = {"name": name}
|
|
971
|
+
|
|
972
|
+
# Convert tuple list to dict and add to payload
|
|
973
|
+
if ports is not None:
|
|
974
|
+
for items in ports:
|
|
975
|
+
port_range = [{"start": items[2]}]
|
|
976
|
+
if len(items) == 4:
|
|
977
|
+
port_range.append({"end": items[3]})
|
|
978
|
+
payload.setdefault(f"{items[0]}{items[1].title()}Ports", []).extend(
|
|
979
|
+
port_range
|
|
980
|
+
)
|
|
981
|
+
|
|
982
|
+
# Add optional parameters to payload
|
|
983
|
+
for key, value in kwargs.items():
|
|
984
|
+
payload[snake_to_camel(key)] = value
|
|
985
|
+
|
|
986
|
+
response = self.rest.post("networkServices", json=payload)
|
|
987
|
+
if isinstance(response, Response):
|
|
988
|
+
# this is only true when the creation failed (status code is not 2xx)
|
|
989
|
+
status_code = response.status_code
|
|
990
|
+
# Handle error response
|
|
991
|
+
raise Exception(
|
|
992
|
+
f"API call failed with status {status_code}: {response.json()}"
|
|
993
|
+
)
|
|
994
|
+
return response
|
|
995
|
+
|
|
996
|
+
def update_network_service(
|
|
997
|
+
self, service_id: str, ports: list = None, **kwargs
|
|
998
|
+
) -> Box:
|
|
999
|
+
"""
|
|
1000
|
+
Updates the specified Network Service.
|
|
1001
|
+
|
|
1002
|
+
If ports aren't provided then no changes will be made to the ports already defined. If ports are provided then
|
|
1003
|
+
the existing ports will be overwritten.
|
|
1004
|
+
|
|
1005
|
+
Args:
|
|
1006
|
+
service_id (str): The unique ID for the Network Service.
|
|
1007
|
+
ports (list):
|
|
1008
|
+
A list of port protocol tuples. Tuples must follow the convention `src/dest`, `protocol`, `start port`,
|
|
1009
|
+
`end port`. If this is a single port and not a port range then `end port` can be omitted. E.g.
|
|
1010
|
+
|
|
1011
|
+
.. code-block:: python
|
|
1012
|
+
|
|
1013
|
+
('src', 'tcp', '49152', '65535'),
|
|
1014
|
+
('dest', 'tcp', '22),
|
|
1015
|
+
('dest', 'tcp', '9010', '9012'),
|
|
1016
|
+
('dest', 'udp', '9010', '9012')
|
|
1017
|
+
|
|
1018
|
+
**kwargs: Optional keyword args.
|
|
1019
|
+
|
|
1020
|
+
Keyword Args:
|
|
1021
|
+
description (str): Additional information on the Network Service.
|
|
1022
|
+
|
|
1023
|
+
Returns:
|
|
1024
|
+
:obj:`Box`: The newly created Network Service resource record.
|
|
1025
|
+
|
|
1026
|
+
Examples:
|
|
1027
|
+
Update the name and description for a Network Service:
|
|
1028
|
+
|
|
1029
|
+
>>> zia.firewall.update_network_service('959093',
|
|
1030
|
+
... name='MS Exchange',
|
|
1031
|
+
... description='All ports related to the MS Exchange service.')
|
|
1032
|
+
|
|
1033
|
+
Updates the ports for a Network Service, leaving other fields intact:
|
|
1034
|
+
|
|
1035
|
+
>>> zia.firewall.add_network_service('959093',
|
|
1036
|
+
... ports=[
|
|
1037
|
+
... ('dest', 'tcp', '500', '510')])
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
"""
|
|
1041
|
+
payload = {
|
|
1042
|
+
snake_to_camel(k): v
|
|
1043
|
+
for k, v in self.get_network_service(service_id).items()
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
# Convert tuple list to dict and add to payload
|
|
1047
|
+
if ports is not None:
|
|
1048
|
+
# Clear existing ports and set new values
|
|
1049
|
+
for items in ports:
|
|
1050
|
+
port_key = f"{items[0]}{items[1].title()}Ports"
|
|
1051
|
+
payload[port_key] = []
|
|
1052
|
+
payload[port_key].append({"start": items[2]})
|
|
1053
|
+
if len(items) == 4:
|
|
1054
|
+
payload[port_key].append({"end": items[3]})
|
|
1055
|
+
|
|
1056
|
+
# Add optional parameters to payload
|
|
1057
|
+
for key, value in kwargs.items():
|
|
1058
|
+
payload[snake_to_camel(key)] = value
|
|
1059
|
+
|
|
1060
|
+
resp = self.rest.put(f"networkServices/{service_id}", json=payload).status_code
|
|
1061
|
+
|
|
1062
|
+
# Return the object if it was updated successfully
|
|
1063
|
+
if not isinstance(resp, Response):
|
|
1064
|
+
return self.get_network_service(service_id)
|
|
1065
|
+
|
|
1066
|
+
def list_time_windows(self) -> Box:
|
|
1067
|
+
"""
|
|
1068
|
+
Returns a list of time intervals used for by the Firewall policy or the URL Filtering policy.
|
|
1069
|
+
|
|
1070
|
+
Args:
|
|
1071
|
+
id (int): The unique id for the Time Interval.
|
|
1072
|
+
name (str): The name of the Time Interval.
|
|
1073
|
+
|
|
1074
|
+
Returns:
|
|
1075
|
+
:obj:`Box`: The ZIA Time Interval resource record.
|
|
1076
|
+
|
|
1077
|
+
Examples:
|
|
1078
|
+
>>> pprint(zia.firewall.list_time_windows_lite)
|
|
1079
|
+
|
|
1080
|
+
"""
|
|
1081
|
+
response = self.rest.get("/timeWindows")
|
|
1082
|
+
if isinstance(response, Response):
|
|
1083
|
+
return None
|
|
1084
|
+
return response
|
|
1085
|
+
|
|
1086
|
+
def list_time_windows_lite(self) -> Box:
|
|
1087
|
+
"""
|
|
1088
|
+
Returns name and ID dictionary of time intervals used by the Firewall policy or the URL Filtering policy.
|
|
1089
|
+
|
|
1090
|
+
Args:
|
|
1091
|
+
id (int): The unique id for the Time Interval.
|
|
1092
|
+
name (str): The name of the Time Interval.
|
|
1093
|
+
|
|
1094
|
+
Returns:
|
|
1095
|
+
:obj:`Box`: The ZIA Time Interval resource record.
|
|
1096
|
+
|
|
1097
|
+
Examples:
|
|
1098
|
+
>>> pprint(zia.firewall.list_time_windows_lite)
|
|
1099
|
+
|
|
1100
|
+
"""
|
|
1101
|
+
response = self.rest.get("/timeWindows/lite")
|
|
1102
|
+
if isinstance(response, Response):
|
|
1103
|
+
return None
|
|
1104
|
+
return response
|