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.
Files changed (73) hide show
  1. illumio_pylo/API/APIConnector.py +1308 -0
  2. illumio_pylo/API/AuditLog.py +42 -0
  3. illumio_pylo/API/ClusterHealth.py +136 -0
  4. illumio_pylo/API/CredentialsManager.py +286 -0
  5. illumio_pylo/API/Explorer.py +1077 -0
  6. illumio_pylo/API/JsonPayloadTypes.py +240 -0
  7. illumio_pylo/API/RuleSearchQuery.py +128 -0
  8. illumio_pylo/API/__init__.py +0 -0
  9. illumio_pylo/AgentStore.py +139 -0
  10. illumio_pylo/Exception.py +44 -0
  11. illumio_pylo/Helpers/__init__.py +3 -0
  12. illumio_pylo/Helpers/exports.py +508 -0
  13. illumio_pylo/Helpers/functions.py +166 -0
  14. illumio_pylo/IPList.py +135 -0
  15. illumio_pylo/IPMap.py +285 -0
  16. illumio_pylo/Label.py +25 -0
  17. illumio_pylo/LabelCommon.py +48 -0
  18. illumio_pylo/LabelGroup.py +68 -0
  19. illumio_pylo/LabelStore.py +403 -0
  20. illumio_pylo/LabeledObject.py +25 -0
  21. illumio_pylo/Organization.py +258 -0
  22. illumio_pylo/Query.py +331 -0
  23. illumio_pylo/ReferenceTracker.py +41 -0
  24. illumio_pylo/Rule.py +671 -0
  25. illumio_pylo/Ruleset.py +306 -0
  26. illumio_pylo/RulesetStore.py +101 -0
  27. illumio_pylo/SecurityPrincipal.py +62 -0
  28. illumio_pylo/Service.py +256 -0
  29. illumio_pylo/SoftwareVersion.py +125 -0
  30. illumio_pylo/VirtualService.py +17 -0
  31. illumio_pylo/VirtualServiceStore.py +75 -0
  32. illumio_pylo/Workload.py +506 -0
  33. illumio_pylo/WorkloadStore.py +289 -0
  34. illumio_pylo/__init__.py +82 -0
  35. illumio_pylo/cli/NativeParsers.py +96 -0
  36. illumio_pylo/cli/__init__.py +134 -0
  37. illumio_pylo/cli/__main__.py +10 -0
  38. illumio_pylo/cli/commands/__init__.py +32 -0
  39. illumio_pylo/cli/commands/credential_manager.py +168 -0
  40. illumio_pylo/cli/commands/iplist_import_from_file.py +185 -0
  41. illumio_pylo/cli/commands/misc.py +7 -0
  42. illumio_pylo/cli/commands/ruleset_export.py +129 -0
  43. illumio_pylo/cli/commands/update_pce_objects_cache.py +44 -0
  44. illumio_pylo/cli/commands/ven_duplicate_remover.py +366 -0
  45. illumio_pylo/cli/commands/ven_idle_to_visibility.py +287 -0
  46. illumio_pylo/cli/commands/ven_upgrader.py +226 -0
  47. illumio_pylo/cli/commands/workload_export.py +251 -0
  48. illumio_pylo/cli/commands/workload_import.py +423 -0
  49. illumio_pylo/cli/commands/workload_relabeler.py +510 -0
  50. illumio_pylo/cli/commands/workload_reset_names_to_null.py +83 -0
  51. illumio_pylo/cli/commands/workload_used_in_rule_finder.py +80 -0
  52. illumio_pylo/docs/Doxygen +1757 -0
  53. illumio_pylo/tmp.py +104 -0
  54. illumio_pylo/utilities/__init__.py +0 -0
  55. illumio_pylo/utilities/cli.py +10 -0
  56. illumio_pylo/utilities/credentials.example.json +20 -0
  57. illumio_pylo/utilities/explorer_report_exporter.py +86 -0
  58. illumio_pylo/utilities/health_monitoring.py +102 -0
  59. illumio_pylo/utilities/iplist_analyzer.py +148 -0
  60. illumio_pylo/utilities/iplists_stats_duplicates_unused_finder.py +75 -0
  61. illumio_pylo/utilities/resources/iplists-import-example.csv +3 -0
  62. illumio_pylo/utilities/resources/iplists-import-example.xlsx +0 -0
  63. illumio_pylo/utilities/resources/workload-exporter-filter-example.csv +3 -0
  64. illumio_pylo/utilities/resources/workloads-import-example.csv +2 -0
  65. illumio_pylo/utilities/resources/workloads-import-example.xlsx +0 -0
  66. illumio_pylo/utilities/ven_compatibility_report_export.py +240 -0
  67. illumio_pylo/utilities/ven_idle_to_illumination.py +344 -0
  68. illumio_pylo/utilities/ven_reassign_pce.py +183 -0
  69. illumio_pylo-0.2.5.dist-info/LICENSE +176 -0
  70. illumio_pylo-0.2.5.dist-info/METADATA +197 -0
  71. illumio_pylo-0.2.5.dist-info/RECORD +73 -0
  72. illumio_pylo-0.2.5.dist-info/WHEEL +5 -0
  73. illumio_pylo-0.2.5.dist-info/top_level.txt +1 -0
@@ -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
+