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/IPList.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
from typing import Dict, Optional
|
|
2
|
+
|
|
3
|
+
import illumio_pylo as pylo
|
|
4
|
+
from .API.JsonPayloadTypes import IPListObjectJsonStructure
|
|
5
|
+
from illumio_pylo import log
|
|
6
|
+
from .Helpers import *
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class IPList(pylo.ReferenceTracker):
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
:type owner: IPListStore
|
|
13
|
+
:type description: str|None
|
|
14
|
+
:type raw_entries: dict[str,str]
|
|
15
|
+
"""
|
|
16
|
+
name: str
|
|
17
|
+
href: str
|
|
18
|
+
|
|
19
|
+
def __init__(self, name: str, href: str, owner: 'pylo.IPListStore', description=None):
|
|
20
|
+
"""
|
|
21
|
+
:type name: str
|
|
22
|
+
:type href: str
|
|
23
|
+
:type owner: IPListStore
|
|
24
|
+
"""
|
|
25
|
+
pylo.ReferenceTracker.__init__(self)
|
|
26
|
+
self.owner = owner
|
|
27
|
+
self.name = name
|
|
28
|
+
self.href = href
|
|
29
|
+
self.description = description
|
|
30
|
+
self.raw_json = None
|
|
31
|
+
self.raw_entries = {}
|
|
32
|
+
|
|
33
|
+
def count_entries(self) -> int:
|
|
34
|
+
return len(self.raw_entries)
|
|
35
|
+
|
|
36
|
+
def load_from_json(self, json_input: IPListObjectJsonStructure):
|
|
37
|
+
self.raw_json = json_input
|
|
38
|
+
|
|
39
|
+
ip_ranges_array = json_input.get("ip_ranges")
|
|
40
|
+
if ip_ranges_array is None:
|
|
41
|
+
raise pylo.PyloEx("cannot find 'ip_ranges' in IPList JSON:\n" + nice_json(json_input))
|
|
42
|
+
|
|
43
|
+
for ip_range in ip_ranges_array:
|
|
44
|
+
from_ip = ip_range.get("from_ip")
|
|
45
|
+
if from_ip is None:
|
|
46
|
+
raise pylo.PyloEx("cannot find 'from_ip' in IPList JSON:\n" + nice_json(ip_range))
|
|
47
|
+
|
|
48
|
+
slash_pos = from_ip.find('/')
|
|
49
|
+
if slash_pos < 0:
|
|
50
|
+
to_ip = ip_range.get("to_ip")
|
|
51
|
+
if to_ip is None:
|
|
52
|
+
entry = from_ip
|
|
53
|
+
else:
|
|
54
|
+
if len(to_ip) < 4:
|
|
55
|
+
entry = from_ip + "/" + to_ip
|
|
56
|
+
else:
|
|
57
|
+
entry = from_ip + '-' + to_ip
|
|
58
|
+
else:
|
|
59
|
+
entry = from_ip
|
|
60
|
+
|
|
61
|
+
exclusion = ip_range.get('exclusion')
|
|
62
|
+
if exclusion is not None and exclusion:
|
|
63
|
+
entry = '!' + entry
|
|
64
|
+
|
|
65
|
+
self.raw_entries[entry] = entry
|
|
66
|
+
|
|
67
|
+
def get_ip4map(self) -> pylo.IP4Map:
|
|
68
|
+
map = pylo.IP4Map()
|
|
69
|
+
|
|
70
|
+
for entry in self.raw_entries:
|
|
71
|
+
if entry[0] == '!':
|
|
72
|
+
map.subtract_from_text(entry[1:], ignore_ipv6=True)
|
|
73
|
+
else:
|
|
74
|
+
map.add_from_text(entry, ignore_ipv6=True)
|
|
75
|
+
|
|
76
|
+
return map
|
|
77
|
+
|
|
78
|
+
def get_raw_entries_as_string_list(self, separator=',') -> str:
|
|
79
|
+
return pylo.string_list_to_text(self.raw_entries.values(), separator=separator)
|
|
80
|
+
|
|
81
|
+
def get_api_reference_json(self):
|
|
82
|
+
return {'ip_list': {'href': self.href}}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class IPListStore:
|
|
86
|
+
items_by_href: Dict[str, 'pylo.IPList']
|
|
87
|
+
|
|
88
|
+
def __init__(self, owner: 'pylo.Organization'):
|
|
89
|
+
self.owner = owner
|
|
90
|
+
self.items_by_href = {}
|
|
91
|
+
|
|
92
|
+
def count(self) -> int:
|
|
93
|
+
return len(self.items_by_href)
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def iplists(self) -> list['pylo.IPList']:
|
|
97
|
+
return list(self.items_by_href.values())
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def iplists_by_href(self) -> Dict[str, 'pylo.IPList']:
|
|
101
|
+
return self.items_by_href.copy()
|
|
102
|
+
|
|
103
|
+
def load_iplists_from_json(self, json_list: list[IPListObjectJsonStructure]):
|
|
104
|
+
for json_item in json_list:
|
|
105
|
+
if 'name' not in json_item or 'href' not in json_item:
|
|
106
|
+
raise Exception("Cannot find 'value'/name or href for iplist in JSON:\n" + nice_json(json_item))
|
|
107
|
+
new_iplist_name = json_item['name']
|
|
108
|
+
new_iplist_href = json_item['href']
|
|
109
|
+
new_iplist_desc = json_item.get('description')
|
|
110
|
+
|
|
111
|
+
new_iplist = pylo.IPList(new_iplist_name, new_iplist_href, self, new_iplist_desc)
|
|
112
|
+
new_iplist.load_from_json(json_item)
|
|
113
|
+
|
|
114
|
+
if new_iplist_href in self.items_by_href:
|
|
115
|
+
raise Exception("A iplist with href '%s' already exists in the table", new_iplist_href)
|
|
116
|
+
|
|
117
|
+
self.items_by_href[new_iplist_href] = new_iplist
|
|
118
|
+
|
|
119
|
+
log.debug("Found iplist '%s' with href '%s'", new_iplist_name, new_iplist_href)
|
|
120
|
+
|
|
121
|
+
def find_by_href(self, href: str) -> Optional['pylo.IPList']:
|
|
122
|
+
return self.items_by_href.get(href)
|
|
123
|
+
|
|
124
|
+
def find_by_name(self, name: str, case_sensitive: bool = True ) -> Optional['pylo.IPList']:
|
|
125
|
+
if case_sensitive:
|
|
126
|
+
for iplist in self.items_by_href.values():
|
|
127
|
+
if iplist.name == name:
|
|
128
|
+
return iplist
|
|
129
|
+
else:
|
|
130
|
+
lower_name = name.lower()
|
|
131
|
+
for iplist in self.items_by_href.values():
|
|
132
|
+
if iplist.name.lower() == lower_name:
|
|
133
|
+
return iplist
|
|
134
|
+
return None
|
|
135
|
+
|
illumio_pylo/IPMap.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
from .Exception import PyloEx
|
|
2
|
+
from .Helpers.functions import is_valid_ipv6, string_list_to_text
|
|
3
|
+
import ipaddress
|
|
4
|
+
import copy
|
|
5
|
+
from typing import Optional, List, Dict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def sort_first(val):
|
|
9
|
+
return val[0]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
start = 0
|
|
13
|
+
end = 1
|
|
14
|
+
|
|
15
|
+
masks = []
|
|
16
|
+
mask = 0
|
|
17
|
+
for i in range(32):
|
|
18
|
+
mask |= 1 << i
|
|
19
|
+
masks.append(mask)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class IP4Map:
|
|
23
|
+
def __init__(self):
|
|
24
|
+
self._entries = []
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def ip_entry_from_text(entry: str, ignore_ipv6=True) -> Optional[List[int]]:
|
|
28
|
+
new_entry = None
|
|
29
|
+
|
|
30
|
+
dash_find = entry.find('-')
|
|
31
|
+
|
|
32
|
+
if dash_find > 0:
|
|
33
|
+
# this is a range entry
|
|
34
|
+
start_txt = entry[0:dash_find]
|
|
35
|
+
if ignore_ipv6 and is_valid_ipv6(start_txt):
|
|
36
|
+
return None
|
|
37
|
+
end_txt = entry[dash_find+1:]
|
|
38
|
+
if ignore_ipv6 and is_valid_ipv6(end_txt):
|
|
39
|
+
return None
|
|
40
|
+
start_ip_object = ipaddress.IPv4Address(start_txt)
|
|
41
|
+
end_ip_object = ipaddress.IPv4Address(end_txt)
|
|
42
|
+
new_entry = [int(start_ip_object), int(end_ip_object)]
|
|
43
|
+
if new_entry[start] > new_entry[end]:
|
|
44
|
+
raise PyloEx("Invalid IP Ranged entered with start address > end address: {}".format(entry))
|
|
45
|
+
|
|
46
|
+
elif entry.find('/') > 0:
|
|
47
|
+
# This is a network entry
|
|
48
|
+
network_str = entry[0:(entry.find('/'))]
|
|
49
|
+
if ignore_ipv6 and (is_valid_ipv6(network_str) or network_str == '::'):
|
|
50
|
+
return None
|
|
51
|
+
ip_object = ipaddress.IPv4Network(entry)
|
|
52
|
+
new_entry = [int(ip_object.network_address), int(ip_object.broadcast_address)]
|
|
53
|
+
if ignore_ipv6 and is_valid_ipv6(ip_object.network_address.__str__()):
|
|
54
|
+
return None
|
|
55
|
+
else:
|
|
56
|
+
if ignore_ipv6 and is_valid_ipv6(entry):
|
|
57
|
+
return None
|
|
58
|
+
ip_object = ipaddress.IPv4Address(entry)
|
|
59
|
+
new_entry = [int(ip_object), int(ip_object)]
|
|
60
|
+
|
|
61
|
+
return new_entry
|
|
62
|
+
|
|
63
|
+
def add_from_text(self, entry: str, skip_recalculation=False, ignore_ipv6=True):
|
|
64
|
+
|
|
65
|
+
new_entry = self.ip_entry_from_text(entry, ignore_ipv6=ignore_ipv6)
|
|
66
|
+
|
|
67
|
+
if ignore_ipv6 and new_entry is None:
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
if not skip_recalculation:
|
|
71
|
+
self._entries.append(new_entry)
|
|
72
|
+
self.sort_and_recalculate()
|
|
73
|
+
|
|
74
|
+
def intersection(self, another_map: 'IP4Map'):
|
|
75
|
+
|
|
76
|
+
inverted_map = IP4Map()
|
|
77
|
+
inverted_map.add_from_text('0.0.0.0-255.255.255.255')
|
|
78
|
+
|
|
79
|
+
inverted_map.substract(another_map)
|
|
80
|
+
|
|
81
|
+
result = copy.deepcopy(self)
|
|
82
|
+
result.substract(inverted_map)
|
|
83
|
+
|
|
84
|
+
return result
|
|
85
|
+
|
|
86
|
+
def contains(self, another_map: 'IP4Map') -> bool:
|
|
87
|
+
|
|
88
|
+
if len(self._entries) < 1:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
copy_of_map = copy.deepcopy(another_map)
|
|
92
|
+
copy_of_map.substract(self)
|
|
93
|
+
|
|
94
|
+
if len(copy_of_map._entries) < 1:
|
|
95
|
+
return True
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
def substract(self, another_map: 'IP4Map'):
|
|
99
|
+
affected_rows = 0
|
|
100
|
+
for entry in another_map._entries:
|
|
101
|
+
affected_rows += self.substract_single_entry(entry)
|
|
102
|
+
return affected_rows
|
|
103
|
+
|
|
104
|
+
def substract_single_entry(self, sub_entry: []) -> int:
|
|
105
|
+
affected_rows = 0
|
|
106
|
+
updated_entries = []
|
|
107
|
+
|
|
108
|
+
for entry in self._entries:
|
|
109
|
+
if sub_entry[end] < entry[start] or sub_entry[start] > entry[end]:
|
|
110
|
+
# no overlap at all, entry is left untouched
|
|
111
|
+
updated_entries.append(entry)
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
affected_rows += 1
|
|
115
|
+
if sub_entry[start] <= entry[start]:
|
|
116
|
+
if sub_entry[end] >= entry[end]:
|
|
117
|
+
# complete overlap, remove entry
|
|
118
|
+
continue
|
|
119
|
+
else:
|
|
120
|
+
entry[start] = sub_entry[end] + 1
|
|
121
|
+
updated_entries.append(entry)
|
|
122
|
+
else:
|
|
123
|
+
updated_entries.append([entry[start], sub_entry[start] - 1])
|
|
124
|
+
if sub_entry[end] < entry[end]:
|
|
125
|
+
updated_entries.append([sub_entry[end] + 1, entry[end]])
|
|
126
|
+
|
|
127
|
+
self._entries = updated_entries
|
|
128
|
+
|
|
129
|
+
return affected_rows
|
|
130
|
+
|
|
131
|
+
def subtract_from_text(self, entry: str, ignore_ipv6=False):
|
|
132
|
+
|
|
133
|
+
new_entry = self.ip_entry_from_text(entry, ignore_ipv6=ignore_ipv6)
|
|
134
|
+
|
|
135
|
+
if new_entry is None:
|
|
136
|
+
return 0
|
|
137
|
+
|
|
138
|
+
return self.substract_single_entry(new_entry)
|
|
139
|
+
|
|
140
|
+
def sort_and_recalculate(self):
|
|
141
|
+
new_entries = []
|
|
142
|
+
|
|
143
|
+
self._entries.sort(key=sort_first)
|
|
144
|
+
|
|
145
|
+
cursor = None # current entry being processed
|
|
146
|
+
for entry in self._entries:
|
|
147
|
+
if cursor is None: # usually the first entry
|
|
148
|
+
cursor = entry
|
|
149
|
+
continue
|
|
150
|
+
|
|
151
|
+
# if current entry has no overlap with cursor entry then cursor entry is added to result array and cursor
|
|
152
|
+
# is set to current entry and loop starts again
|
|
153
|
+
if entry[start] > cursor[end]:
|
|
154
|
+
new_entries.append(cursor)
|
|
155
|
+
cursor = entry
|
|
156
|
+
continue
|
|
157
|
+
|
|
158
|
+
# if current entry's end is greater than cursor entry's end then cursor entry's end is set to current
|
|
159
|
+
# entry's end and loop starts again
|
|
160
|
+
if entry[end] > cursor[end]:
|
|
161
|
+
cursor[end] = entry[end]
|
|
162
|
+
continue
|
|
163
|
+
|
|
164
|
+
# if current entry's end is less or equal to cursor entry's end then there is nothing to do and loop
|
|
165
|
+
# starts again
|
|
166
|
+
if entry[end] <= cursor[end]:
|
|
167
|
+
continue
|
|
168
|
+
|
|
169
|
+
raise PyloEx("Error while sorting IP4Map, unexpected value found: entry({}-{}) cursor({}-{})".format(
|
|
170
|
+
ipaddress.IPv4Address(entry[start]),
|
|
171
|
+
ipaddress.IPv4Address(entry[end]),
|
|
172
|
+
ipaddress.IPv4Address(cursor[start]),
|
|
173
|
+
ipaddress.IPv4Address(cursor[end])
|
|
174
|
+
))
|
|
175
|
+
|
|
176
|
+
# in case there is still a cursor entry left, add it to result array
|
|
177
|
+
if cursor is not None:
|
|
178
|
+
new_entries.append(cursor)
|
|
179
|
+
|
|
180
|
+
self._entries = new_entries
|
|
181
|
+
|
|
182
|
+
def to_string_list(self, separator=','):
|
|
183
|
+
ranges = []
|
|
184
|
+
|
|
185
|
+
for entry in self._entries:
|
|
186
|
+
ranges.append('{}-{}'.format(ipaddress.IPv4Address(entry[start]), ipaddress.IPv4Address(entry[end])))
|
|
187
|
+
|
|
188
|
+
return string_list_to_text(ranges, separator=separator)
|
|
189
|
+
|
|
190
|
+
def to_list_of_string(self):
|
|
191
|
+
ranges = []
|
|
192
|
+
|
|
193
|
+
for entry in self._entries:
|
|
194
|
+
if entry[start] == entry[end]:
|
|
195
|
+
ranges.append('{}'.format(ipaddress.IPv4Address(entry[start])))
|
|
196
|
+
else:
|
|
197
|
+
ranges.append('{}-{}'.format(ipaddress.IPv4Address(entry[start]), ipaddress.IPv4Address(entry[end])))
|
|
198
|
+
|
|
199
|
+
return ranges
|
|
200
|
+
|
|
201
|
+
def to_list_of_cidr_string(self, skip_netmask_for_32=False):
|
|
202
|
+
|
|
203
|
+
result = []
|
|
204
|
+
|
|
205
|
+
for entry in self._entries:
|
|
206
|
+
|
|
207
|
+
net_start = entry[start]
|
|
208
|
+
net_end = entry[end]
|
|
209
|
+
|
|
210
|
+
previous_loop_end = net_start
|
|
211
|
+
|
|
212
|
+
while net_start <= net_end:
|
|
213
|
+
|
|
214
|
+
if net_start == net_end:
|
|
215
|
+
if skip_netmask_for_32:
|
|
216
|
+
result.append('{}'.format(ipaddress.IPv4Address(net_start)))
|
|
217
|
+
else:
|
|
218
|
+
result.append('{}'.format(ipaddress.IPv4Address(net_start), 32))
|
|
219
|
+
break
|
|
220
|
+
|
|
221
|
+
for netmask in range(1, 32, 1):
|
|
222
|
+
new_end = net_start | masks[netmask]
|
|
223
|
+
#print("{}/{}/{}/{}".format(ipaddress.IPv4Address(net_start), ipaddress.IPv4Address(net_end), ipaddress.IPv4Address(new_end), 32 - netmask))
|
|
224
|
+
|
|
225
|
+
if new_end > net_end:
|
|
226
|
+
result.append('{}/{}'.format(ipaddress.IPv4Address(net_start), 33 - netmask))
|
|
227
|
+
net_start = previous_loop_end + 1
|
|
228
|
+
previous_loop_end = net_start
|
|
229
|
+
#print("breaking loop with {}/{}".format(ipaddress.IPv4Address(net_start), ipaddress.IPv4Address(previous_loop_end)))
|
|
230
|
+
break
|
|
231
|
+
|
|
232
|
+
if new_end == net_end:
|
|
233
|
+
if skip_netmask_for_32 and netmask == 0:
|
|
234
|
+
result.append('{}'.format(ipaddress.IPv4Address(net_start)))
|
|
235
|
+
else:
|
|
236
|
+
result.append('{}/{}'.format(ipaddress.IPv4Address(net_start), 32 - netmask))
|
|
237
|
+
net_start = net_end+1
|
|
238
|
+
break
|
|
239
|
+
else:
|
|
240
|
+
previous_loop_end = new_end
|
|
241
|
+
|
|
242
|
+
return result
|
|
243
|
+
|
|
244
|
+
def count_ips(self) -> int:
|
|
245
|
+
count = 0
|
|
246
|
+
for entry in self._entries:
|
|
247
|
+
count += entry[1] - entry[0] + 1
|
|
248
|
+
|
|
249
|
+
return count
|
|
250
|
+
|
|
251
|
+
def count_entries(self) -> int:
|
|
252
|
+
return len(self._entries)
|
|
253
|
+
|
|
254
|
+
def print_to_std(self, header=None, padding='', list_marker=' - '):
|
|
255
|
+
if header is not None:
|
|
256
|
+
print('{}{}({} entries)'.format(
|
|
257
|
+
padding,
|
|
258
|
+
header,
|
|
259
|
+
len(self._entries)))
|
|
260
|
+
|
|
261
|
+
for entry in self._entries:
|
|
262
|
+
if entry[0] == entry[1]:
|
|
263
|
+
print('{}{}{}'.format(padding, list_marker, ipaddress.IPv4Address(entry[0])))
|
|
264
|
+
else:
|
|
265
|
+
print('{}{}{}-{}'.format(padding, list_marker, ipaddress.IPv4Address(entry[0]), ipaddress.IPv4Address(entry[1])))
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
# test = IP4Map()
|
|
269
|
+
# test.add_from_text('10.0.0.0/16')
|
|
270
|
+
# test.add_from_text('10.0.0.0-10.2.50.50')
|
|
271
|
+
# test.add_from_text('192.168.1.2')
|
|
272
|
+
# test.add_from_text('1.0.0.0/8')
|
|
273
|
+
# test.add_from_text('192.168.1.0-192.168.2.0')
|
|
274
|
+
# test.subtract_from_text('192.168.0.0-192.168.1.255')
|
|
275
|
+
#
|
|
276
|
+
# test.add_from_text('200.0.0.0-200.1.255.255')
|
|
277
|
+
# test.subtract_from_text('199.255.255.255-200.1.0.0') # should produce 200.1.0.1-200.1.255.255
|
|
278
|
+
#
|
|
279
|
+
# test.add_from_text('200.10.0.0-200.11.255.255')
|
|
280
|
+
# test.subtract_from_text('200.10.10.10-200.11.0.0') # should produce 200.10.0.0-200.10.10.9 and 200.11.0.1-200.11.255.255
|
|
281
|
+
#
|
|
282
|
+
# test.add_from_text('200.20.0.0-200.21.255.255')
|
|
283
|
+
# test.subtract_from_text('200.20.10.10-200.22.0.0') # should produce 200.20.0.0-200.20.10.9
|
|
284
|
+
#
|
|
285
|
+
# test.print_to_std(header="Show IP4Map test:", padding='')
|
illumio_pylo/Label.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .API.JsonPayloadTypes import LabelHrefRef
|
|
2
|
+
from .ReferenceTracker import ReferenceTracker
|
|
3
|
+
from .LabelCommon import LabelCommon
|
|
4
|
+
from .LabelStore import LabelStore
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Label(ReferenceTracker, LabelCommon):
|
|
8
|
+
def __init__(self, name, href, label_type: str, owner: 'LabelStore'):
|
|
9
|
+
ReferenceTracker.__init__(self)
|
|
10
|
+
LabelCommon.__init__(self, name, href, label_type, owner)
|
|
11
|
+
|
|
12
|
+
def is_group(self) -> bool:
|
|
13
|
+
return False
|
|
14
|
+
|
|
15
|
+
def is_label(self) -> bool:
|
|
16
|
+
return True
|
|
17
|
+
|
|
18
|
+
def reference_obj(self):
|
|
19
|
+
return {"href": self.href,
|
|
20
|
+
"value": self.name,
|
|
21
|
+
"key": self.type}
|
|
22
|
+
|
|
23
|
+
def get_api_reference_json(self) -> LabelHrefRef:
|
|
24
|
+
return {'label': {'href': self.href}}
|
|
25
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
from .Exception import PyloEx
|
|
3
|
+
from .LabelStore import label_type_role, label_type_env, label_type_loc, label_type_app, LabelStore
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LabelCommon:
|
|
7
|
+
|
|
8
|
+
def __init__(self, name: str, href: str, label_type: str, owner: LabelStore):
|
|
9
|
+
self.owner: LabelStore = owner
|
|
10
|
+
self.name: str = name
|
|
11
|
+
self.href: str = href
|
|
12
|
+
self.type = label_type
|
|
13
|
+
|
|
14
|
+
def is_label(self) -> bool:
|
|
15
|
+
raise PyloEx("not implemented")
|
|
16
|
+
|
|
17
|
+
def is_group(self) -> bool:
|
|
18
|
+
raise PyloEx("not implemented")
|
|
19
|
+
|
|
20
|
+
def type_to_short_string(self) -> str:
|
|
21
|
+
return self.type
|
|
22
|
+
|
|
23
|
+
def type_is_location(self) -> bool:
|
|
24
|
+
return self.type == 'loc'
|
|
25
|
+
|
|
26
|
+
def type_is_environment(self) -> bool:
|
|
27
|
+
return self.type == 'env'
|
|
28
|
+
|
|
29
|
+
def type_is_application(self) -> bool:
|
|
30
|
+
return self.type == 'app'
|
|
31
|
+
|
|
32
|
+
def type_is_role(self) -> bool:
|
|
33
|
+
return self.type == 'role'
|
|
34
|
+
|
|
35
|
+
def type_string(self) -> str:
|
|
36
|
+
return self.type
|
|
37
|
+
|
|
38
|
+
def api_set_name(self, new_name: str):
|
|
39
|
+
find_collision = self.owner.find_label_by_name_and_type(new_name, self.type)
|
|
40
|
+
if find_collision is not self:
|
|
41
|
+
raise PyloEx("A Label/LabelGroup with name '{}' already exists".format(new_name))
|
|
42
|
+
|
|
43
|
+
if self.is_group():
|
|
44
|
+
self.owner.owner.connector.objects_labelgroup_update(self.href, data={'name': new_name})
|
|
45
|
+
else:
|
|
46
|
+
self.owner.owner.connector.objects_label_update(self.href, data={'value': new_name})
|
|
47
|
+
|
|
48
|
+
self.name = new_name
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from typing import Dict, Union
|
|
2
|
+
import illumio_pylo as pylo
|
|
3
|
+
from typing import *
|
|
4
|
+
|
|
5
|
+
from illumio_pylo import Label
|
|
6
|
+
from .API.JsonPayloadTypes import LabelGroupObjectJsonStructure
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LabelGroup(pylo.ReferenceTracker, pylo.LabelCommon):
|
|
10
|
+
|
|
11
|
+
def __init__(self, name: str, href: str, label_type: str, owner):
|
|
12
|
+
pylo.ReferenceTracker.__init__(self)
|
|
13
|
+
pylo.LabelCommon.__init__(self, name, href, label_type, owner)
|
|
14
|
+
self._members_by_href: Dict[str, Union['pylo.Label', 'pylo.LabelGroup']] = {}
|
|
15
|
+
self.raw_json: Optional[LabelGroupObjectJsonStructure] = None
|
|
16
|
+
|
|
17
|
+
def load_from_json(self):
|
|
18
|
+
# print(self.raw_json)
|
|
19
|
+
if 'labels' in self.raw_json:
|
|
20
|
+
for href_record in self.raw_json['labels']:
|
|
21
|
+
if 'href' in href_record:
|
|
22
|
+
find_label = self.owner.find_by_href(href_record['href'])
|
|
23
|
+
if find_label is None:
|
|
24
|
+
raise pylo.PyloEx(f"LabelGroup named '{self.name}' has member with href '{href_record['href']}' not found")
|
|
25
|
+
find_label.add_reference(self)
|
|
26
|
+
self._members_by_href[find_label.href] = find_label
|
|
27
|
+
else:
|
|
28
|
+
raise pylo.PyloEx('LabelGroup member has no HREF')
|
|
29
|
+
|
|
30
|
+
def expand_nested_to_dict_by_href(self) -> Dict[str, 'pylo.Label']:
|
|
31
|
+
results = {}
|
|
32
|
+
for label in self._members_by_href.values():
|
|
33
|
+
if isinstance(label, pylo.Label):
|
|
34
|
+
results[label.href] = label
|
|
35
|
+
elif isinstance(label, pylo.LabelGroup):
|
|
36
|
+
for nested_label in label.expand_nested_to_dict_by_href().values():
|
|
37
|
+
results[nested_label.href] = nested_label
|
|
38
|
+
else:
|
|
39
|
+
raise pylo.PyloEx("Unsupported object type {}".format(type(label)))
|
|
40
|
+
return results
|
|
41
|
+
|
|
42
|
+
def expand_nested_to_array(self) -> List['pylo.Label']:
|
|
43
|
+
return list(self.expand_nested_to_dict_by_href().values())
|
|
44
|
+
|
|
45
|
+
def get_api_reference_json(self) -> Dict:
|
|
46
|
+
return {'label_group': {'href': self.href}}
|
|
47
|
+
|
|
48
|
+
def get_members(self) -> Dict[str, 'pylo.Label']:
|
|
49
|
+
data = {}
|
|
50
|
+
for label in self._members_by_href.values():
|
|
51
|
+
data[label.href] = label
|
|
52
|
+
return data
|
|
53
|
+
|
|
54
|
+
def get_members_count(self) -> int:
|
|
55
|
+
return len(self._members_by_href)
|
|
56
|
+
|
|
57
|
+
def has_member_with_href(self, href: str) -> bool:
|
|
58
|
+
return href in self._members_by_href
|
|
59
|
+
|
|
60
|
+
def has_member_object(self, label: 'pylo.Label') -> bool:
|
|
61
|
+
return label.href in self._members_by_href
|
|
62
|
+
|
|
63
|
+
def is_group(self) -> bool:
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
def is_label(self) -> bool:
|
|
67
|
+
return False
|
|
68
|
+
|