illumio-pylo 0.2.5__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.
- illumio_pylo/API/APIConnector.py +1308 -0
- illumio_pylo/API/AuditLog.py +42 -0
- illumio_pylo/API/ClusterHealth.py +136 -0
- illumio_pylo/API/CredentialsManager.py +286 -0
- illumio_pylo/API/Explorer.py +1077 -0
- illumio_pylo/API/JsonPayloadTypes.py +240 -0
- illumio_pylo/API/RuleSearchQuery.py +128 -0
- illumio_pylo/API/__init__.py +0 -0
- illumio_pylo/AgentStore.py +139 -0
- illumio_pylo/Exception.py +44 -0
- illumio_pylo/Helpers/__init__.py +3 -0
- illumio_pylo/Helpers/exports.py +508 -0
- illumio_pylo/Helpers/functions.py +166 -0
- illumio_pylo/IPList.py +135 -0
- illumio_pylo/IPMap.py +285 -0
- illumio_pylo/Label.py +25 -0
- illumio_pylo/LabelCommon.py +48 -0
- illumio_pylo/LabelGroup.py +68 -0
- illumio_pylo/LabelStore.py +403 -0
- illumio_pylo/LabeledObject.py +25 -0
- illumio_pylo/Organization.py +258 -0
- illumio_pylo/Query.py +331 -0
- illumio_pylo/ReferenceTracker.py +41 -0
- illumio_pylo/Rule.py +671 -0
- illumio_pylo/Ruleset.py +306 -0
- illumio_pylo/RulesetStore.py +101 -0
- illumio_pylo/SecurityPrincipal.py +62 -0
- illumio_pylo/Service.py +256 -0
- illumio_pylo/SoftwareVersion.py +125 -0
- illumio_pylo/VirtualService.py +17 -0
- illumio_pylo/VirtualServiceStore.py +75 -0
- illumio_pylo/Workload.py +506 -0
- illumio_pylo/WorkloadStore.py +289 -0
- illumio_pylo/__init__.py +82 -0
- illumio_pylo/cli/NativeParsers.py +96 -0
- illumio_pylo/cli/__init__.py +134 -0
- illumio_pylo/cli/__main__.py +10 -0
- illumio_pylo/cli/commands/__init__.py +32 -0
- illumio_pylo/cli/commands/credential_manager.py +168 -0
- illumio_pylo/cli/commands/iplist_import_from_file.py +185 -0
- illumio_pylo/cli/commands/misc.py +7 -0
- illumio_pylo/cli/commands/ruleset_export.py +129 -0
- illumio_pylo/cli/commands/update_pce_objects_cache.py +44 -0
- illumio_pylo/cli/commands/ven_duplicate_remover.py +366 -0
- illumio_pylo/cli/commands/ven_idle_to_visibility.py +287 -0
- illumio_pylo/cli/commands/ven_upgrader.py +226 -0
- illumio_pylo/cli/commands/workload_export.py +251 -0
- illumio_pylo/cli/commands/workload_import.py +423 -0
- illumio_pylo/cli/commands/workload_relabeler.py +510 -0
- illumio_pylo/cli/commands/workload_reset_names_to_null.py +83 -0
- illumio_pylo/cli/commands/workload_used_in_rule_finder.py +80 -0
- illumio_pylo/docs/Doxygen +1757 -0
- illumio_pylo/tmp.py +104 -0
- illumio_pylo/utilities/__init__.py +0 -0
- illumio_pylo/utilities/cli.py +10 -0
- illumio_pylo/utilities/credentials.example.json +20 -0
- illumio_pylo/utilities/explorer_report_exporter.py +86 -0
- illumio_pylo/utilities/health_monitoring.py +102 -0
- illumio_pylo/utilities/iplist_analyzer.py +148 -0
- illumio_pylo/utilities/iplists_stats_duplicates_unused_finder.py +75 -0
- illumio_pylo/utilities/resources/iplists-import-example.csv +3 -0
- illumio_pylo/utilities/resources/iplists-import-example.xlsx +0 -0
- illumio_pylo/utilities/resources/workload-exporter-filter-example.csv +3 -0
- illumio_pylo/utilities/resources/workloads-import-example.csv +2 -0
- illumio_pylo/utilities/resources/workloads-import-example.xlsx +0 -0
- illumio_pylo/utilities/ven_compatibility_report_export.py +240 -0
- illumio_pylo/utilities/ven_idle_to_illumination.py +344 -0
- illumio_pylo/utilities/ven_reassign_pce.py +183 -0
- illumio_pylo-0.2.5.dist-info/LICENSE +176 -0
- illumio_pylo-0.2.5.dist-info/METADATA +197 -0
- illumio_pylo-0.2.5.dist-info/RECORD +73 -0
- illumio_pylo-0.2.5.dist-info/WHEEL +5 -0
- illumio_pylo-0.2.5.dist-info/top_level.txt +1 -0
illumio_pylo/Ruleset.py
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
from typing import Optional, List, Union, Dict
|
|
2
|
+
|
|
3
|
+
import illumio_pylo as pylo
|
|
4
|
+
from .API.JsonPayloadTypes import RuleObjectJsonStructure, RulesetObjectJsonStructure, \
|
|
5
|
+
RulesetScopeEntryLineJsonStructure
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
ruleset_id_extraction_regex = re.compile(r"^/orgs/([0-9]+)/sec_policy/([0-9]+)?(draft)?/rule_sets/(?P<id>[0-9]+)$")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RulesetScope:
|
|
12
|
+
|
|
13
|
+
def __init__(self, owner: 'pylo.Ruleset'):
|
|
14
|
+
self.owner: 'pylo.Ruleset' = owner
|
|
15
|
+
self.scope_entries: Dict['pylo.RulesetScopeEntry', 'pylo.RulesetScopeEntry'] = {}
|
|
16
|
+
|
|
17
|
+
def load_from_json(self, data: List[List[RulesetScopeEntryLineJsonStructure]]):
|
|
18
|
+
for scope_json in data:
|
|
19
|
+
scope_entry = pylo.RulesetScopeEntry(self)
|
|
20
|
+
scope_entry.load_from_json(scope_json)
|
|
21
|
+
self.scope_entries[scope_entry] = scope_entry
|
|
22
|
+
|
|
23
|
+
def get_all_scopes_str(self, label_separator='|', scope_separator="\n", use_href: bool = False):
|
|
24
|
+
result = ''
|
|
25
|
+
for scope in self.scope_entries.keys():
|
|
26
|
+
if len(result) < 1:
|
|
27
|
+
result += scope.to_string(label_separator,use_href=use_href)
|
|
28
|
+
else:
|
|
29
|
+
result += scope_separator
|
|
30
|
+
result += scope.to_string(label_separator,use_href=use_href)
|
|
31
|
+
|
|
32
|
+
return result
|
|
33
|
+
|
|
34
|
+
def has_at_least_one_all_all_all(self) -> bool:
|
|
35
|
+
for scope_entry in self.scope_entries:
|
|
36
|
+
if scope_entry.is_all_all_all():
|
|
37
|
+
return True
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
class RulesetScopeEntry:
|
|
41
|
+
|
|
42
|
+
def __init__(self, owner: 'pylo.RulesetScope'):
|
|
43
|
+
self.owner: pylo.RulesetScope = owner
|
|
44
|
+
self._labels: Dict[str, Union['pylo.Label', 'pylo.LabelGroup']] = {}
|
|
45
|
+
|
|
46
|
+
def load_from_json(self, data: List[RulesetScopeEntryLineJsonStructure]):
|
|
47
|
+
#log.error(pylo.nice_json(data))
|
|
48
|
+
l_store = self.owner.owner.owner.owner.LabelStore
|
|
49
|
+
for label_json in data:
|
|
50
|
+
label_entry = label_json.get('label')
|
|
51
|
+
if label_entry is None:
|
|
52
|
+
label_entry = label_json.get('label_group')
|
|
53
|
+
if label_entry is None:
|
|
54
|
+
raise pylo.PyloEx("Cannot find 'label' or 'label_group' entry in scope: {}".format(pylo.nice_json(label_json)))
|
|
55
|
+
href_entry = label_entry.get('href')
|
|
56
|
+
if href_entry is None:
|
|
57
|
+
raise pylo.PyloEx("Cannot find 'href' entry in scope: {}".format(pylo.nice_json(data)))
|
|
58
|
+
|
|
59
|
+
label = l_store.find_by_href(href_entry)
|
|
60
|
+
if label is None:
|
|
61
|
+
raise pylo.PyloEx("Cannot find label with href '{}' in Ruleset '{}' scope: {}".format(href_entry,
|
|
62
|
+
self.owner.owner.name,
|
|
63
|
+
pylo.nice_json(data)))
|
|
64
|
+
|
|
65
|
+
if label.type not in self.owner.owner.owner.owner.LabelStore.label_types_as_set:
|
|
66
|
+
raise pylo.PyloEx("Unsupported label type '{}' named '{}' in scope of ruleset '{}'/'{}'".format(label.type_string(),
|
|
67
|
+
label.name,
|
|
68
|
+
self.owner.owner.href,
|
|
69
|
+
self.owner.owner.name))
|
|
70
|
+
self._labels[label.type] = label
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def labels(self) -> List[Union['pylo.Label', 'pylo.LabelGroup']]:
|
|
74
|
+
"""
|
|
75
|
+
Return a copy of the labels list
|
|
76
|
+
"""
|
|
77
|
+
return list(self._labels.values())
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def labels_sorted_by_type(self) -> List[Union['pylo.Label', 'pylo.LabelGroup']]:
|
|
81
|
+
"""
|
|
82
|
+
Return a copy of the labels list sorted by type which are defined by the LabelStore
|
|
83
|
+
"""
|
|
84
|
+
return pylo.LabelStore.Utils.list_sort_by_type(self._labels.values(), self.owner.owner.owner.owner.LabelStore.label_types)
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def labels_by_type(self) -> Dict[str, Union['pylo.Label', 'pylo.LabelGroup']]:
|
|
88
|
+
"""
|
|
89
|
+
Return a copy of the labels dict keyed by label type
|
|
90
|
+
:return:
|
|
91
|
+
"""
|
|
92
|
+
return self._labels.copy()
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def labels_by_href(self) -> Dict[str, Union['pylo.Label', 'pylo.LabelGroup']]:
|
|
96
|
+
"""
|
|
97
|
+
Return labels dict keyed by label href
|
|
98
|
+
:return:
|
|
99
|
+
"""
|
|
100
|
+
return {label.href: label for label in self._labels.values()}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def to_string(self, label_separator = '|', use_href=False):
|
|
104
|
+
string = 'All' + label_separator
|
|
105
|
+
if self.app_label is not None:
|
|
106
|
+
if use_href:
|
|
107
|
+
string = self.app_label.href + label_separator
|
|
108
|
+
else:
|
|
109
|
+
string = self.app_label.name + label_separator
|
|
110
|
+
|
|
111
|
+
if self.env_label is None:
|
|
112
|
+
string += 'All' + label_separator
|
|
113
|
+
else:
|
|
114
|
+
if use_href:
|
|
115
|
+
string += self.env_label.href + label_separator
|
|
116
|
+
else:
|
|
117
|
+
string += self.env_label.name + label_separator
|
|
118
|
+
|
|
119
|
+
if self.loc_label is None:
|
|
120
|
+
string += 'All'
|
|
121
|
+
else:
|
|
122
|
+
if use_href:
|
|
123
|
+
string += self.loc_label.href
|
|
124
|
+
else:
|
|
125
|
+
string += self.loc_label.name
|
|
126
|
+
|
|
127
|
+
return string
|
|
128
|
+
|
|
129
|
+
def is_all_all_all(self):
|
|
130
|
+
return len(self._labels) == 0
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def loc_label(self) -> Optional['pylo.Label']:
|
|
134
|
+
"""
|
|
135
|
+
@deprecated
|
|
136
|
+
:return:
|
|
137
|
+
"""
|
|
138
|
+
return self._labels.get('loc')
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def env_label(self) -> Optional['pylo.Label']:
|
|
142
|
+
"""
|
|
143
|
+
@deprecated
|
|
144
|
+
:return:
|
|
145
|
+
"""
|
|
146
|
+
return self._labels.get('env')
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def app_label(self) -> Optional['pylo.Label']:
|
|
150
|
+
"""
|
|
151
|
+
@deprecated
|
|
152
|
+
:return:
|
|
153
|
+
"""
|
|
154
|
+
return self._labels.get('app')
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class Ruleset:
|
|
158
|
+
|
|
159
|
+
name: str
|
|
160
|
+
href: Optional[str]
|
|
161
|
+
description: str
|
|
162
|
+
|
|
163
|
+
def __init__(self, owner: 'pylo.RulesetStore'):
|
|
164
|
+
self.owner: 'pylo.RulesetStore' = owner
|
|
165
|
+
self.href: Optional[str] = None
|
|
166
|
+
self.name: str = ''
|
|
167
|
+
self.description: str = ''
|
|
168
|
+
self.scopes: 'pylo.RulesetScope' = pylo.RulesetScope(self)
|
|
169
|
+
# must keep an ordered list of rules while the dict by href is there for quick searches
|
|
170
|
+
self._rules_by_href: Dict[str, 'pylo.Rule'] = {}
|
|
171
|
+
self._rules: List['pylo.Rule'] = []
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def rules(self):
|
|
175
|
+
"""
|
|
176
|
+
Return a copy of the rules list
|
|
177
|
+
:return:
|
|
178
|
+
"""
|
|
179
|
+
return self._rules.copy()
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def rules_by_href(self):
|
|
183
|
+
"""
|
|
184
|
+
Return a copy of the rules dict keyed by href
|
|
185
|
+
:return:
|
|
186
|
+
"""
|
|
187
|
+
return self._rules_by_href.copy()
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def rules_ordered_by_type(self):
|
|
191
|
+
"""
|
|
192
|
+
Return a list of rules ordered by type (Intra Scope First)
|
|
193
|
+
:return:
|
|
194
|
+
"""
|
|
195
|
+
rules: List[pylo.Rule] = []
|
|
196
|
+
for rule in self._rules:
|
|
197
|
+
if rule.is_intra_scope():
|
|
198
|
+
rules.append(rule)
|
|
199
|
+
for rule in self._rules:
|
|
200
|
+
if not rule.is_intra_scope():
|
|
201
|
+
rules.append(rule)
|
|
202
|
+
return rules
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def load_from_json(self, data: RulesetObjectJsonStructure):
|
|
206
|
+
if 'name' not in data:
|
|
207
|
+
raise pylo.PyloEx("Cannot find Ruleset name in JSON data: \n" + pylo.Helpers.nice_json(data))
|
|
208
|
+
self.name = data['name']
|
|
209
|
+
|
|
210
|
+
if 'href' not in data:
|
|
211
|
+
raise pylo.PyloEx("Cannot find Ruleset href in JSON data: \n" + pylo.Helpers.nice_json(data))
|
|
212
|
+
self.href = data['href']
|
|
213
|
+
|
|
214
|
+
scopes_json = data.get('scopes')
|
|
215
|
+
if scopes_json is None:
|
|
216
|
+
raise pylo.PyloEx("Cannot find Ruleset scope in JSON data: \n" + pylo.Helpers.nice_json(data))
|
|
217
|
+
|
|
218
|
+
self.description = data.get('description')
|
|
219
|
+
if self.description is None:
|
|
220
|
+
self.description = ''
|
|
221
|
+
|
|
222
|
+
self.scopes.load_from_json(scopes_json)
|
|
223
|
+
|
|
224
|
+
if 'rules' in data:
|
|
225
|
+
for rule_data in data['rules']:
|
|
226
|
+
self.load_single_rule_from_json(rule_data)
|
|
227
|
+
|
|
228
|
+
def load_single_rule_from_json(self, rule_data: RuleObjectJsonStructure) -> 'pylo.Rule':
|
|
229
|
+
new_rule = pylo.Rule(self)
|
|
230
|
+
new_rule.load_from_json(rule_data)
|
|
231
|
+
self._rules_by_href[new_rule.href] = new_rule
|
|
232
|
+
self._rules.append(new_rule)
|
|
233
|
+
return new_rule
|
|
234
|
+
|
|
235
|
+
def api_delete_rule(self, rule_or_href: Union[str, 'pylo.Rule']):
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
:param rule_or_href: HRef string or a Rule object to be deleted
|
|
239
|
+
"""
|
|
240
|
+
href = rule_or_href
|
|
241
|
+
if isinstance(rule_or_href, pylo.Rule):
|
|
242
|
+
href = rule_or_href.href
|
|
243
|
+
|
|
244
|
+
find_object = self._rules_by_href.get(href)
|
|
245
|
+
if find_object is None:
|
|
246
|
+
raise pylo.PyloEx("Cannot delete a Rule with href={} which is not part of ruleset {}/{}".format(href, self.name, self.href))
|
|
247
|
+
|
|
248
|
+
self.owner.owner.connector.objects_rule_delete(href)
|
|
249
|
+
del self._rules_by_href[href]
|
|
250
|
+
self._rules.remove(find_object)
|
|
251
|
+
|
|
252
|
+
def api_create_rule(self, intra_scope: bool,
|
|
253
|
+
consumers: List['pylo.RuleActorsAcceptableTypes'],
|
|
254
|
+
providers: List['pylo.RuleActorsAcceptableTypes'],
|
|
255
|
+
services: List[Union['pylo.Service', 'pylo.DirectServiceInRule']],
|
|
256
|
+
description='', machine_auth=False, secure_connect=False, enabled=True,
|
|
257
|
+
stateless=False, consuming_security_principals=None,
|
|
258
|
+
resolve_consumers_as_virtual_services=True, resolve_consumers_as_workloads=True,
|
|
259
|
+
resolve_providers_as_virtual_services=True, resolve_providers_as_workloads=True) -> 'pylo.Rule':
|
|
260
|
+
if consuming_security_principals is None:
|
|
261
|
+
consuming_security_principals = []
|
|
262
|
+
|
|
263
|
+
new_rule_json = self.owner.owner.connector.objects_rule_create(
|
|
264
|
+
intra_scope=intra_scope, ruleset_href=self.href,
|
|
265
|
+
consumers=consumers, providers=providers, services=services,
|
|
266
|
+
description=description, machine_auth=machine_auth, secure_connect=secure_connect, enabled=enabled,
|
|
267
|
+
stateless=stateless, consuming_security_principals=consuming_security_principals,
|
|
268
|
+
resolve_consumers_as_virtual_services=resolve_consumers_as_virtual_services,
|
|
269
|
+
resolve_consumers_as_workloads=resolve_consumers_as_workloads,
|
|
270
|
+
resolve_providers_as_virtual_services=resolve_providers_as_virtual_services,
|
|
271
|
+
resolve_providers_as_workloads=resolve_providers_as_workloads
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
return self.load_single_rule_from_json(new_rule_json)
|
|
275
|
+
|
|
276
|
+
def count_rules(self) -> int:
|
|
277
|
+
return len(self._rules)
|
|
278
|
+
|
|
279
|
+
def extract_id_from_href(self) -> int:
|
|
280
|
+
match = ruleset_id_extraction_regex.match(self.href)
|
|
281
|
+
if match is None:
|
|
282
|
+
raise pylo.PyloEx("Cannot extract ruleset_id from href '{}'".format(self.href))
|
|
283
|
+
|
|
284
|
+
return int(match.group("id"))
|
|
285
|
+
|
|
286
|
+
def get_ruleset_url(self, pce_fqdn: str = None, pce_port: int = None) -> str:
|
|
287
|
+
if pce_fqdn is None or pce_port is None:
|
|
288
|
+
connector = pylo.find_connector_or_die(self)
|
|
289
|
+
if pce_fqdn is None:
|
|
290
|
+
pce_fqdn = connector.hostname
|
|
291
|
+
if pce_port is None:
|
|
292
|
+
pce_port = connector.port
|
|
293
|
+
|
|
294
|
+
return 'https://{}:{}/#/rulesets/{}/draft/rules/'.format(pce_fqdn, pce_port, self.extract_id_from_href())
|
|
295
|
+
|
|
296
|
+
def api_set_name(self, new_name: str):
|
|
297
|
+
find_collision = self.owner.find_ruleset_by_name(new_name)
|
|
298
|
+
if find_collision is not self:
|
|
299
|
+
raise pylo.PyloEx("A Ruleset with name '{}' already exists".format(new_name))
|
|
300
|
+
|
|
301
|
+
self.owner.owner.connector.objects_ruleset_update(self.href, update_data={'name': new_name})
|
|
302
|
+
self.name = new_name
|
|
303
|
+
|
|
304
|
+
def api_set_description(self, new_description: str):
|
|
305
|
+
self.owner.owner.connector.objects_ruleset_update(self.href, update_data={'description': new_description})
|
|
306
|
+
self.description = new_description
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from typing import Optional, List, Union, Dict
|
|
2
|
+
|
|
3
|
+
import illumio_pylo as pylo
|
|
4
|
+
from illumio_pylo import log, Organization, PyloEx, Rule, Ruleset
|
|
5
|
+
from .Helpers import nice_json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RulesetStore:
|
|
9
|
+
|
|
10
|
+
def __init__(self, owner: 'pylo.Organization'):
|
|
11
|
+
self.owner: pylo.Organization = owner
|
|
12
|
+
self._items_by_href: Dict[str, 'pylo.Ruleset'] = {}
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def rulesets(self) -> List['pylo.Ruleset']:
|
|
16
|
+
"""
|
|
17
|
+
:return: a copy of the list of rulesets
|
|
18
|
+
"""
|
|
19
|
+
return list(self._items_by_href.values())
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def rulesets_dict_by_href(self) -> Dict[str, 'pylo.Ruleset']:
|
|
23
|
+
"""
|
|
24
|
+
:return: a copy of the dict of rulesets by href
|
|
25
|
+
:return:
|
|
26
|
+
"""
|
|
27
|
+
return self._items_by_href.copy()
|
|
28
|
+
|
|
29
|
+
def count_rulesets(self) -> int:
|
|
30
|
+
return len(self._items_by_href)
|
|
31
|
+
|
|
32
|
+
def count_rules(self) -> int:
|
|
33
|
+
count = 0
|
|
34
|
+
for ruleset in self._items_by_href.values():
|
|
35
|
+
count += ruleset.count_rules()
|
|
36
|
+
|
|
37
|
+
return count
|
|
38
|
+
|
|
39
|
+
def load_rulesets_from_json(self, data):
|
|
40
|
+
for json_item in data:
|
|
41
|
+
self.load_single_ruleset_from_json(json_item)
|
|
42
|
+
|
|
43
|
+
def load_single_ruleset_from_json(self, json_item):
|
|
44
|
+
new_item = Ruleset(self)
|
|
45
|
+
new_item.load_from_json(json_item)
|
|
46
|
+
|
|
47
|
+
if new_item.href in self._items_by_href:
|
|
48
|
+
raise PyloEx(
|
|
49
|
+
"A Ruleset with href '%s' already exists in the table, please check your JSON data for consistency. JSON:\n%s"
|
|
50
|
+
% (new_item.href, nice_json(json_item)))
|
|
51
|
+
|
|
52
|
+
self._items_by_href[new_item.href] = new_item
|
|
53
|
+
|
|
54
|
+
log.debug("Found Ruleset '%s' with href '%s'" % (new_item.name, new_item.href))
|
|
55
|
+
|
|
56
|
+
return new_item
|
|
57
|
+
|
|
58
|
+
def find_rule_by_href(self, href: str) -> Optional['pylo.Rule']:
|
|
59
|
+
for ruleset in self._items_by_href.values():
|
|
60
|
+
rule = ruleset.rules_by_href.get(href)
|
|
61
|
+
if rule is not None:
|
|
62
|
+
return rule
|
|
63
|
+
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
def find_ruleset_by_name(self, name: str, case_sensitive=True) -> Optional['pylo.Ruleset']:
|
|
67
|
+
used_name = name
|
|
68
|
+
if case_sensitive:
|
|
69
|
+
used_name = name.lower()
|
|
70
|
+
|
|
71
|
+
for ruleset in self._items_by_href.values():
|
|
72
|
+
if ruleset.name.lower() == used_name:
|
|
73
|
+
return ruleset
|
|
74
|
+
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
def api_create_ruleset(self, name: str,
|
|
78
|
+
scope_app: 'pylo.Label' = None,
|
|
79
|
+
scope_env: 'pylo.Label' = None,
|
|
80
|
+
scope_loc: 'pylo.Label' = None,
|
|
81
|
+
description: str = '', enabled: bool = True) -> 'pylo.Ruleset':
|
|
82
|
+
|
|
83
|
+
con = self.owner.connector
|
|
84
|
+
json_item = con.objects_ruleset_create(name, scope_app, scope_env, scope_loc, description, enabled)
|
|
85
|
+
return self.load_single_ruleset_from_json(json_item)
|
|
86
|
+
|
|
87
|
+
def api_delete_ruleset(self, ruleset: Union[str, 'pylo.Ruleset']):
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
:param ruleset: should be href string or a Ruleset object
|
|
91
|
+
"""
|
|
92
|
+
href = ruleset
|
|
93
|
+
if isinstance(ruleset, Ruleset):
|
|
94
|
+
href = ruleset.href
|
|
95
|
+
|
|
96
|
+
find_object = self._items_by_href.get(href)
|
|
97
|
+
if find_object is None:
|
|
98
|
+
raise PyloEx("Cannot delete a Ruleset with href={} which is not part of this RulesetStore".format(href))
|
|
99
|
+
|
|
100
|
+
self.owner.connector.objects_ruleset_delete(href)
|
|
101
|
+
del self._items_by_href[href]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
import illumio_pylo as pylo
|
|
3
|
+
from .Helpers import nice_json
|
|
4
|
+
from illumio_pylo import log
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SecurityPrincipal(pylo.ReferenceTracker):
|
|
8
|
+
def __init__(self, name: str, href: str, owner: 'pylo.SecurityPrincipalStore'):
|
|
9
|
+
pylo.ReferenceTracker.__init__(self)
|
|
10
|
+
self.owner: 'pylo.SecurityPrincipalStore' = owner
|
|
11
|
+
self.name: str = name
|
|
12
|
+
self.href: str = href
|
|
13
|
+
self.sid: Optional[str] = None
|
|
14
|
+
self.deleted: bool = False
|
|
15
|
+
|
|
16
|
+
self.raw_json = None
|
|
17
|
+
|
|
18
|
+
def load_from_json(self, data):
|
|
19
|
+
self.raw_json = data
|
|
20
|
+
# print(pylo.nice_json(data))
|
|
21
|
+
|
|
22
|
+
self.sid = data['sid']
|
|
23
|
+
self.deleted = data['deleted']
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SecurityPrincipalStore:
|
|
28
|
+
def __init__(self, owner: 'pylo.Organization'):
|
|
29
|
+
self.owner = owner
|
|
30
|
+
self.itemsByHRef = {} # type: dict[str,pylo.SecurityPrincipal]
|
|
31
|
+
|
|
32
|
+
def load_principals_from_json(self, json_list):
|
|
33
|
+
for json_item in json_list:
|
|
34
|
+
if 'name' not in json_item or 'href' not in json_item:
|
|
35
|
+
raise pylo.PyloEx("Cannot find 'value'/name or href for SecurityPrincipal in JSON:\n" + nice_json(json_item))
|
|
36
|
+
|
|
37
|
+
new_item_name = json_item['name']
|
|
38
|
+
new_item_href = json_item['href']
|
|
39
|
+
|
|
40
|
+
# SecurityPrincipals's name is None when it's provided by VEN through its hostname until it's manually overwritten
|
|
41
|
+
# (eventually) by someone. In such a case, you need to use hostname instead
|
|
42
|
+
if new_item_name is None:
|
|
43
|
+
if 'hostname' not in json_item:
|
|
44
|
+
raise pylo.PyloEx("Cannot find 'value'/hostname in JSON:\n" + nice_json(json_item))
|
|
45
|
+
new_item_name = json_item['hostname']
|
|
46
|
+
|
|
47
|
+
new_item = pylo.SecurityPrincipal(new_item_name, new_item_href, self)
|
|
48
|
+
new_item.load_from_json(json_item)
|
|
49
|
+
|
|
50
|
+
if new_item_href in self.itemsByHRef:
|
|
51
|
+
raise pylo.PyloEx("A SecurityPrincipal with href '%s' already exists in the table", new_item_href)
|
|
52
|
+
|
|
53
|
+
self.itemsByHRef[new_item_href] = new_item
|
|
54
|
+
|
|
55
|
+
log.debug("Found SecurityPrincipal '%s' with href '%s'", new_item_name, new_item_href)
|
|
56
|
+
|
|
57
|
+
def find_by_href(self, href: str) -> Optional[SecurityPrincipal]:
|
|
58
|
+
return self.itemsByHRef.get(href)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|