illumio-pylo 0.3.11__py3-none-any.whl → 0.3.13__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 +138 -106
- illumio_pylo/API/CredentialsManager.py +168 -3
- illumio_pylo/API/Explorer.py +619 -14
- illumio_pylo/API/JsonPayloadTypes.py +64 -4
- illumio_pylo/FilterQuery.py +892 -0
- illumio_pylo/Helpers/exports.py +1 -1
- illumio_pylo/LabelCommon.py +13 -3
- illumio_pylo/LabelDimension.py +109 -0
- illumio_pylo/LabelStore.py +97 -38
- illumio_pylo/WorkloadStore.py +58 -0
- illumio_pylo/__init__.py +9 -3
- illumio_pylo/cli/__init__.py +5 -2
- illumio_pylo/cli/commands/__init__.py +1 -0
- illumio_pylo/cli/commands/credential_manager.py +555 -4
- illumio_pylo/cli/commands/label_delete_unused.py +0 -3
- illumio_pylo/cli/commands/traffic_export.py +358 -0
- illumio_pylo/cli/commands/ui/credential_manager_ui/app.js +638 -0
- illumio_pylo/cli/commands/ui/credential_manager_ui/index.html +217 -0
- illumio_pylo/cli/commands/ui/credential_manager_ui/styles.css +581 -0
- illumio_pylo/cli/commands/update_pce_objects_cache.py +1 -2
- illumio_pylo/cli/commands/ven_duplicate_remover.py +79 -59
- illumio_pylo/cli/commands/workload_export.py +29 -0
- illumio_pylo/utilities/cli.py +4 -1
- illumio_pylo/utilities/health_monitoring.py +5 -1
- {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/METADATA +2 -1
- {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/RECORD +29 -24
- {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/WHEEL +1 -1
- illumio_pylo/Query.py +0 -331
- {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/licenses/LICENSE +0 -0
- {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/top_level.txt +0 -0
illumio_pylo/Query.py
DELETED
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import illumio_pylo as pylo
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def find_chars(text: str, start: int):
|
|
5
|
-
end = len(text)
|
|
6
|
-
return {"ending_parenthesis": text.find(")", start),
|
|
7
|
-
"opening_parenthesis": text.find(")", start),
|
|
8
|
-
"opening_squote": text.find("'", start),
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def find_first_punctuation(text: str, start: int):
|
|
13
|
-
cursor = start
|
|
14
|
-
while cursor < len(text):
|
|
15
|
-
char = text[cursor]
|
|
16
|
-
if char == ')':
|
|
17
|
-
return {'notfound': False, 'position': cursor, 'character': ')'}
|
|
18
|
-
if char == '(':
|
|
19
|
-
return {'notfound': False, 'position': cursor, 'character': '('}
|
|
20
|
-
if char == "'":
|
|
21
|
-
return {'notfound': False, 'position': cursor, 'character': "'"}
|
|
22
|
-
|
|
23
|
-
cursor += 1
|
|
24
|
-
|
|
25
|
-
return {'notfound': True}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class get_block_response:
|
|
29
|
-
def __init__(self, length=None, operator=None, error=None):
|
|
30
|
-
self.length = length
|
|
31
|
-
self.operator = operator
|
|
32
|
-
self.error = error
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def get_block_until_binary_ops_quotes_enabled(data: str):
|
|
36
|
-
|
|
37
|
-
detected_quote = None
|
|
38
|
-
|
|
39
|
-
for pos in range(len(data)):
|
|
40
|
-
|
|
41
|
-
cur_2let = data[pos:pos+2].lower()
|
|
42
|
-
cur_3let = data[pos:pos+3].lower()
|
|
43
|
-
|
|
44
|
-
# print("DEBUG {} {}".format(cur_2let, cur_3let))
|
|
45
|
-
|
|
46
|
-
if cur_2let == 'or':
|
|
47
|
-
if detected_quote is None:
|
|
48
|
-
return get_block_response(length=pos, operator='or')
|
|
49
|
-
elif cur_3let == 'and':
|
|
50
|
-
if detected_quote is None:
|
|
51
|
-
return get_block_response(length=pos, operator='and')
|
|
52
|
-
|
|
53
|
-
cur_char = data[pos]
|
|
54
|
-
|
|
55
|
-
if cur_char == "'":
|
|
56
|
-
if detected_quote is None:
|
|
57
|
-
detected_quote = cur_char
|
|
58
|
-
elif detected_quote == '"':
|
|
59
|
-
continue
|
|
60
|
-
else:
|
|
61
|
-
detected_quote = None
|
|
62
|
-
|
|
63
|
-
elif cur_char == '"':
|
|
64
|
-
if detected_quote is None:
|
|
65
|
-
detected_quote = cur_char
|
|
66
|
-
elif detected_quote == "'":
|
|
67
|
-
continue
|
|
68
|
-
else:
|
|
69
|
-
detected_quote = None
|
|
70
|
-
|
|
71
|
-
if detected_quote is None:
|
|
72
|
-
return get_block_response(length=len(data))
|
|
73
|
-
|
|
74
|
-
return get_block_response(error="some quotes {} were not closed in expression: {}".format(detected_quote, data))
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class Query:
|
|
78
|
-
def __init__(self, level=0):
|
|
79
|
-
self.level = level
|
|
80
|
-
self.subQueries = [] # type: list[pylo.Query]
|
|
81
|
-
self.raw_value = None
|
|
82
|
-
|
|
83
|
-
def parse(self, data: str):
|
|
84
|
-
padding = ''.rjust(self.level*3)
|
|
85
|
-
data_len = len(data)
|
|
86
|
-
self.raw_value = data
|
|
87
|
-
|
|
88
|
-
cursor = 0
|
|
89
|
-
current_block_start = 0
|
|
90
|
-
parenthesis_opened = []
|
|
91
|
-
blocks = []
|
|
92
|
-
reached_end = False
|
|
93
|
-
|
|
94
|
-
print(padding + 'Level {} parsing string "{}"'.format(self.level , data))
|
|
95
|
-
|
|
96
|
-
while cursor < len(data):
|
|
97
|
-
find_punctuation = find_first_punctuation(data, cursor)
|
|
98
|
-
if find_punctuation['notfound']:
|
|
99
|
-
if len(parenthesis_opened) > 0:
|
|
100
|
-
raise pylo.PyloEx("Reached the end of string before closing parenthesis in block: {}".format(data[current_block_start-1:]))
|
|
101
|
-
blocks.append({'type': 'text', 'text': data[current_block_start:]})
|
|
102
|
-
reached_end = True
|
|
103
|
-
print(padding + "{}-{} REACHED END OF STRING".format(self.level, len(blocks)))
|
|
104
|
-
break
|
|
105
|
-
|
|
106
|
-
found_character = find_punctuation['character']
|
|
107
|
-
found_character_position = find_punctuation['position']
|
|
108
|
-
|
|
109
|
-
if found_character == "'":
|
|
110
|
-
find_next_quote = data.find("'", found_character_position+1)
|
|
111
|
-
if find_next_quote == -1:
|
|
112
|
-
raise pylo.PyloEx("Cannot find a matching closing quote from position {} in text: {}".format(found_character_position, data[current_block_start:]))
|
|
113
|
-
cursor = find_next_quote+1
|
|
114
|
-
if cursor >= len(data):
|
|
115
|
-
blocks.append({'type': 'text', 'text': data[current_block_start:]})
|
|
116
|
-
continue
|
|
117
|
-
elif found_character == ")":
|
|
118
|
-
if len(parenthesis_opened) < 1:
|
|
119
|
-
raise pylo.PyloEx("Cannot find a matching opening parenthesis at position #{} in text: {}".format(found_character_position, data[current_block_start:]))
|
|
120
|
-
elif len(parenthesis_opened) == 1:
|
|
121
|
-
parenthesis_opened.pop()
|
|
122
|
-
blocks.append({'type': 'sub', 'text': data[current_block_start:found_character_position]})
|
|
123
|
-
current_block_start = found_character_position + 1
|
|
124
|
-
cursor = current_block_start
|
|
125
|
-
print(padding + "{}-{} REACHED BLOCK-END C PARENTHESIS".format(self.level, len(blocks)))
|
|
126
|
-
continue
|
|
127
|
-
else:
|
|
128
|
-
parenthesis_opened.pop()
|
|
129
|
-
cursor = found_character_position + 1
|
|
130
|
-
print(padding + "{}-{} REACHED MID-BLOCK C PARENTHESIS".format(self.level, len(blocks)))
|
|
131
|
-
continue
|
|
132
|
-
elif found_character == "(":
|
|
133
|
-
parenthesis_opened.append(found_character_position)
|
|
134
|
-
print(padding + "{}-{} FOUND OPENING P".format(self.level, len(blocks)))
|
|
135
|
-
|
|
136
|
-
if (found_character_position == 0 or found_character_position > current_block_start) and len(parenthesis_opened) == 1:
|
|
137
|
-
if found_character_position != 0:
|
|
138
|
-
blocks.append({'type': 'text', 'text': data[current_block_start:found_character_position]})
|
|
139
|
-
current_block_start = found_character_position+1
|
|
140
|
-
cursor = current_block_start
|
|
141
|
-
print(padding + "{}-{} OPENING P WAS FIRST".format(self.level, len(blocks)))
|
|
142
|
-
continue
|
|
143
|
-
else:
|
|
144
|
-
print(padding + "{}-{} OPENING P WAS NOT FIRST".format(self.level, len(blocks)))
|
|
145
|
-
|
|
146
|
-
cursor = found_character_position + 1
|
|
147
|
-
continue
|
|
148
|
-
|
|
149
|
-
cursor += 1
|
|
150
|
-
|
|
151
|
-
if len(parenthesis_opened) > 0:
|
|
152
|
-
raise pylo.PyloEx("Reached the end of string before closing parenthesis in block: {}".format(
|
|
153
|
-
data[current_block_start-1:]))
|
|
154
|
-
|
|
155
|
-
print(padding + "* Query Level {} blocks:".format(self.level))
|
|
156
|
-
for block in blocks:
|
|
157
|
-
print(padding + "- {}: |{}|".format(block['type'], block['text']))
|
|
158
|
-
|
|
159
|
-
# clear empty blocks, they're just noise
|
|
160
|
-
cleared_blocks = []
|
|
161
|
-
for block in blocks:
|
|
162
|
-
if block['type'] == 'text':
|
|
163
|
-
block['text'] = block['text'].strip()
|
|
164
|
-
if len(block['text']) < 1:
|
|
165
|
-
continue
|
|
166
|
-
cleared_blocks.append(block)
|
|
167
|
-
|
|
168
|
-
# now building operator blocks
|
|
169
|
-
operator_blocks = []
|
|
170
|
-
|
|
171
|
-
for block_number in range(len(blocks)):
|
|
172
|
-
block = blocks[block_number]
|
|
173
|
-
if block['type'] == 'sub':
|
|
174
|
-
new_sub_query = Query(self.level+1)
|
|
175
|
-
new_sub_query.parse(block['text'])
|
|
176
|
-
self.subQueries.append(new_sub_query)
|
|
177
|
-
new_block = {'type': 'query', 'query': new_sub_query}
|
|
178
|
-
operator_blocks.append(new_block)
|
|
179
|
-
continue
|
|
180
|
-
|
|
181
|
-
text = block['text']
|
|
182
|
-
found_filter_name = False
|
|
183
|
-
found_filter_operator = False
|
|
184
|
-
|
|
185
|
-
filter_name = None
|
|
186
|
-
filter_operator = None
|
|
187
|
-
find_filter_in_collection = None
|
|
188
|
-
|
|
189
|
-
while True:
|
|
190
|
-
text_len = len(text)
|
|
191
|
-
if text_len < 1:
|
|
192
|
-
break
|
|
193
|
-
print(padding + "* Handling of text block '||{}||'".format(text))
|
|
194
|
-
first_word_end = text.find(' ')
|
|
195
|
-
|
|
196
|
-
if first_word_end < 0:
|
|
197
|
-
first_word = text
|
|
198
|
-
first_word_end = text_len
|
|
199
|
-
else:
|
|
200
|
-
first_word = text[0:first_word_end]
|
|
201
|
-
first_word_lower = first_word.lower()
|
|
202
|
-
print(padding + " - First word '{}'".format(first_word))
|
|
203
|
-
|
|
204
|
-
if first_word_lower == 'or' or first_word_lower == 'and':
|
|
205
|
-
if found_filter_name:
|
|
206
|
-
if not found_filter_operator:
|
|
207
|
-
raise pylo.PyloEx("Found binary operator '{}' while filter '{}' was found but no operator provided in expression '{}'".format(first_word, filter_name, block['text']))
|
|
208
|
-
if find_filter_in_collection.arguments is not None:
|
|
209
|
-
raise pylo.PyloEx(
|
|
210
|
-
"Found binary operator '{}' while filter '{}' with operator '{}' requires arguments in expression '{}'".format(
|
|
211
|
-
first_word, filter_name, filter_operator, block['text']))
|
|
212
|
-
new_block = {'type': 'filter', 'filter': find_filter_in_collection, 'raw_arguments': None}
|
|
213
|
-
operator_blocks.append(new_block)
|
|
214
|
-
found_filter_name = False
|
|
215
|
-
found_filter_operator = False
|
|
216
|
-
|
|
217
|
-
new_block = {'type': 'binary_op', 'value': first_word_lower}
|
|
218
|
-
operator_blocks.append(new_block)
|
|
219
|
-
elif found_filter_name and found_filter_operator:
|
|
220
|
-
block_info = get_block_until_binary_ops_quotes_enabled(text)
|
|
221
|
-
if block_info.error is not None:
|
|
222
|
-
raise pylo.PyloEx(block_info.error)
|
|
223
|
-
|
|
224
|
-
if block_info.length == 0:
|
|
225
|
-
new_block = {'type': 'filter', 'filter': find_filter_in_collection, 'raw_arguments': None}
|
|
226
|
-
operator_blocks.append(new_block)
|
|
227
|
-
print(padding+" - Found no argument (or empty)")
|
|
228
|
-
raise pylo.PyloEx("This should never happen")
|
|
229
|
-
else:
|
|
230
|
-
new_block = {'type': 'filter', 'filter': find_filter_in_collection, 'raw_arguments': text[0:block_info.length].strip()}
|
|
231
|
-
operator_blocks.append(new_block)
|
|
232
|
-
print(padding + " - Found argument ||{}|| stopped by {}".format(new_block['raw_arguments'], block_info.operator))
|
|
233
|
-
|
|
234
|
-
found_filter_name = False
|
|
235
|
-
found_filter_operator = False
|
|
236
|
-
|
|
237
|
-
first_word_end = block_info.length - 1
|
|
238
|
-
|
|
239
|
-
elif not found_filter_name and not found_filter_operator:
|
|
240
|
-
filter_name = first_word
|
|
241
|
-
found_filter_name = True
|
|
242
|
-
find_filter_in_collection = FilterCollections.workload_filters.get(filter_name)
|
|
243
|
-
if find_filter_in_collection is None:
|
|
244
|
-
raise pylo.PyloEx("Cannot find a filter named '{}' in expression '{}'".format(filter_name, block['text']))
|
|
245
|
-
elif found_filter_name and not found_filter_operator:
|
|
246
|
-
filter_operator = first_word
|
|
247
|
-
found_filter_operator = True
|
|
248
|
-
find_filter_in_collection = find_filter_in_collection.get(filter_operator)
|
|
249
|
-
if find_filter_in_collection is None:
|
|
250
|
-
raise pylo.PyloEx("Cannot find a filter operator '{}' for filter named '{}' in expression '{}'".format(filter_operator, filter_name, block['text']))
|
|
251
|
-
|
|
252
|
-
if first_word_end >= text_len:
|
|
253
|
-
break
|
|
254
|
-
text = text[first_word_end + 1:].strip()
|
|
255
|
-
|
|
256
|
-
# showing blocks to check how well we did
|
|
257
|
-
for block in operator_blocks:
|
|
258
|
-
print(block)
|
|
259
|
-
|
|
260
|
-
# todo: optimize/handle inverters
|
|
261
|
-
|
|
262
|
-
def execute_on_single_object(self, object):
|
|
263
|
-
if len(self.subQueries) == 1:
|
|
264
|
-
pass
|
|
265
|
-
|
|
266
|
-
return False
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
class Filter:
|
|
270
|
-
def __init__(self, name: str, func, arguments=None):
|
|
271
|
-
self.name = name
|
|
272
|
-
self.function = func
|
|
273
|
-
self.arguments = arguments
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
class WorkloadFilter(Filter):
|
|
277
|
-
def __init__(self, name: str, func, arguments = None):
|
|
278
|
-
Filter.__init__(self, name, func, arguments)
|
|
279
|
-
|
|
280
|
-
def do_filter(self, workload: pylo.Workload):
|
|
281
|
-
return self.function(workload)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
class FilterContext:
|
|
285
|
-
def __init__(self, argument, math_op=None):
|
|
286
|
-
self.math_op = math_op
|
|
287
|
-
self.argument = argument
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
class FilterCollections:
|
|
291
|
-
workload_filters = {} # type: dict[str,WorkloadFilter]
|
|
292
|
-
|
|
293
|
-
@staticmethod
|
|
294
|
-
def add_workload_filter(name: str, operator: str, func, arguments=None):
|
|
295
|
-
new_filter = WorkloadFilter(name, func)
|
|
296
|
-
if FilterCollections.workload_filters.get(name) is None:
|
|
297
|
-
FilterCollections.workload_filters[name.lower()] = {}
|
|
298
|
-
|
|
299
|
-
if FilterCollections.workload_filters[name.lower()].get(operator) is not None:
|
|
300
|
-
raise pylo.PyloEx("Filter named '{}' with operator '{}' is already defined".format(name, operator))
|
|
301
|
-
FilterCollections.workload_filters[name.lower()][operator.lower()] = new_filter
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
def tmp_func(wkl: pylo.Workload, context: FilterContext):
|
|
305
|
-
return wkl.get_name() == context.argument
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
FilterCollections.add_workload_filter('name', 'matches', tmp_func, 'string')
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
def tmp_func(wkl: pylo.Workload, context: FilterContext):
|
|
312
|
-
if context.math_op == '>':
|
|
313
|
-
return wkl.count_references() > context.argument
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
FilterCollections.add_workload_filter('reference.count', '<>=!', tmp_func, 'int')
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
def tmp_func(wkl: pylo.Workload, context: FilterContext):
|
|
320
|
-
return context.argument in wkl.description
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
FilterCollections.add_workload_filter('description', 'contains', tmp_func, 'string')
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
File without changes
|
|
File without changes
|