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.
Files changed (30) hide show
  1. illumio_pylo/API/APIConnector.py +138 -106
  2. illumio_pylo/API/CredentialsManager.py +168 -3
  3. illumio_pylo/API/Explorer.py +619 -14
  4. illumio_pylo/API/JsonPayloadTypes.py +64 -4
  5. illumio_pylo/FilterQuery.py +892 -0
  6. illumio_pylo/Helpers/exports.py +1 -1
  7. illumio_pylo/LabelCommon.py +13 -3
  8. illumio_pylo/LabelDimension.py +109 -0
  9. illumio_pylo/LabelStore.py +97 -38
  10. illumio_pylo/WorkloadStore.py +58 -0
  11. illumio_pylo/__init__.py +9 -3
  12. illumio_pylo/cli/__init__.py +5 -2
  13. illumio_pylo/cli/commands/__init__.py +1 -0
  14. illumio_pylo/cli/commands/credential_manager.py +555 -4
  15. illumio_pylo/cli/commands/label_delete_unused.py +0 -3
  16. illumio_pylo/cli/commands/traffic_export.py +358 -0
  17. illumio_pylo/cli/commands/ui/credential_manager_ui/app.js +638 -0
  18. illumio_pylo/cli/commands/ui/credential_manager_ui/index.html +217 -0
  19. illumio_pylo/cli/commands/ui/credential_manager_ui/styles.css +581 -0
  20. illumio_pylo/cli/commands/update_pce_objects_cache.py +1 -2
  21. illumio_pylo/cli/commands/ven_duplicate_remover.py +79 -59
  22. illumio_pylo/cli/commands/workload_export.py +29 -0
  23. illumio_pylo/utilities/cli.py +4 -1
  24. illumio_pylo/utilities/health_monitoring.py +5 -1
  25. {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/METADATA +2 -1
  26. {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/RECORD +29 -24
  27. {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/WHEEL +1 -1
  28. illumio_pylo/Query.py +0 -331
  29. {illumio_pylo-0.3.11.dist-info → illumio_pylo-0.3.13.dist-info}/licenses/LICENSE +0 -0
  30. {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
-