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
@@ -2,15 +2,16 @@ from typing import Dict, List, Literal, Optional
2
2
  import datetime
3
3
  import click
4
4
  import argparse
5
+ import os
5
6
 
6
7
  import illumio_pylo as pylo
7
- from illumio_pylo import ExcelHeader, nice_json
8
+ from illumio_pylo import ExcelHeader
8
9
 
9
10
  from .utils.misc import make_filename_with_timestamp
10
11
  from . import Command
11
12
 
12
13
  command_name = 'ven-duplicate-remover'
13
- objects_load_filter = ['labels']
14
+ objects_load_filter = ['labels', 'workloads']
14
15
 
15
16
 
16
17
  def fill_parser(parser: argparse.ArgumentParser):
@@ -37,8 +38,18 @@ def fill_parser(parser: argparse.ArgumentParser):
37
38
  parser.add_argument('--limit-number-of-deleted-workloads', '-l', type=int, default=None,
38
39
  help='Limit the number of workloads to be deleted, for a limited test run for example.')
39
40
 
41
+ # New option: don't delete if labels mismatch across duplicates
42
+ parser.add_argument('--do-not-delete-if-labels-mismatch', action='store_true',
43
+ help='Do not delete workloads for a duplicated hostname if the workloads do not all have the same set of labels')
44
+
45
+ # New option: ignore PCE online status and allow online workloads to be considered for deletion
46
+ parser.add_argument('--ignore-pce-online-status', action='store_true',
47
+ help='Bypass the logic that keeps online workloads; when set online workloads will be treated like offline ones for deletion decisions')
48
+
40
49
  parser.add_argument('--output-dir', '-o', type=str, required=False, default="output",
41
50
  help='Directory where to write the report file(s)')
51
+ parser.add_argument('--output-filename', type=str, default=None,
52
+ help='Write report to the specified file (or basename) instead of using the default timestamped filename. If multiple formats are requested, the provided path\'s extension will be replaced/added per format.')
42
53
 
43
54
 
44
55
  def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
@@ -55,11 +66,16 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
55
66
  arg_do_not_delete_if_last_heartbeat_is_more_recent_than = args['do_not_delete_if_last_heartbeat_is_more_recent_than']
56
67
  arg_override_pce_offline_timer_to = args['override_pce_offline_timer_to']
57
68
  arg_limit_number_of_deleted_workloads = args['limit_number_of_deleted_workloads']
58
- arg_report_output_dir: str = args['output_dir']
59
-
60
- output_file_prefix = make_filename_with_timestamp('ven-duplicate-removal_', arg_report_output_dir)
61
- output_file_csv = output_file_prefix + '.csv'
62
- output_file_excel = output_file_prefix + '.xlsx'
69
+ arg_ignore_pce_online_status = args['ignore_pce_online_status'] is True
70
+ arg_do_not_delete_if_labels_mismatch = args['do_not_delete_if_labels_mismatch'] is True
71
+ arg_report_output_dir: str = args['output_dir']
72
+
73
+ # Determine output filename behavior: user provided filename/basename or use timestamped prefix
74
+ arg_output_filename: Optional[str] = args.get('output_filename')
75
+ if arg_output_filename is None:
76
+ output_file_prefix = make_filename_with_timestamp('ven-duplicate-removal_', arg_report_output_dir)
77
+ else:
78
+ output_file_prefix = None
63
79
 
64
80
  csv_report_headers = pylo.ExcelHeaderSet([
65
81
  ExcelHeader(name='name', max_width=40),
@@ -88,47 +104,11 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
88
104
  raise pylo.PyloEx("Cannot find label '{}' in the PCE".format(label_name))
89
105
  filter_labels.append(label)
90
106
 
91
- # <editor-fold desc="Download workloads from PCE">
92
- if not pce_cache_was_used:
93
- print("* Downloading Workloads data from the PCE (it may take moment for large amounts of workloads) ... ", flush=True, end='')
94
- if args['filter_label'] is None:
95
- workloads_json = org.connector.objects_workload_get(async_mode=True, max_results=1000000)
96
- else:
97
- filter_labels_list_of_list: List[List[pylo.Label]] = []
98
- # convert filter_labels dict to an array of arrays
99
- for label_type, label_list in org.LabelStore.Utils.list_to_dict_by_type(filter_labels).items():
100
- filter_labels_list_of_list.append(label_list)
101
-
102
- # convert filter_labels_list_of_list to a matrix of all possibilities
103
- # example: [[a,b],[c,d]] becomes [[a,c],[a,d],[b,c],[b,d]]
104
- filter_labels_matrix = [[]]
105
- for label_list in filter_labels_list_of_list:
106
- new_matrix = []
107
- for label in label_list:
108
- for row in filter_labels_matrix:
109
- new_row = row.copy()
110
- new_row.append(label.href)
111
- new_matrix.append(new_row)
112
- filter_labels_matrix = new_matrix
113
-
114
- workloads_json = org.connector.objects_workload_get(async_mode=False, max_results=1000000, filter_by_label=filter_labels_matrix)
115
-
116
- org.WorkloadStore.load_workloads_from_json(workloads_json)
117
-
118
- print("OK! {} workloads loaded".format(org.WorkloadStore.count_workloads()))
119
- # </editor-fold>
120
-
121
- all_workloads: List[pylo.Workload] # the list of all workloads to be processed
122
-
123
- if pce_cache_was_used:
124
- # if some filters were used, let's apply them now
125
- print("* Filtering workloads loaded from cache based on their labels... ", end='', flush=True)
126
- # if some label filters were used, we will apply them at later stage
127
- all_workloads: List[pylo.Workload] = list((org.WorkloadStore.find_workloads_matching_all_labels(filter_labels)).values())
128
- print("OK! {} workloads left after filtering".format(len(all_workloads)))
129
- else:
130
- # filter was already applied during the download from the PCE
131
- all_workloads = org.WorkloadStore.workloads
107
+ # if some filters were used, let's apply them now
108
+ print("* Filtering workloads loaded based on their labels... ", end='', flush=True)
109
+ # if some label filters were used, we will apply them at later stage
110
+ all_workloads: List[pylo.Workload] = list((org.WorkloadStore.find_workloads_matching_all_labels(filter_labels)).values())
111
+ print("OK! {} workloads left after filtering".format(len(all_workloads)))
132
112
 
133
113
  def add_workload_to_report(workload: pylo.Workload, action: str):
134
114
  url_link_to_pce = workload.get_pce_ui_url()
@@ -147,9 +127,8 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
147
127
 
148
128
  sheet.add_line_from_object(new_row)
149
129
 
150
- duplicated_hostnames = DuplicateRecordManager(arg_override_pce_offline_timer_to)
151
-
152
130
  print(" * Looking for VEN with duplicated hostname(s)")
131
+ duplicated_hostnames = DuplicateRecordManager(arg_override_pce_offline_timer_to)
153
132
 
154
133
  for workload in all_workloads:
155
134
  if workload.deleted:
@@ -161,10 +140,12 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
161
140
 
162
141
  print(" * Found {} duplicated hostnames".format(duplicated_hostnames.count_duplicates()))
163
142
 
164
- delete_tracker = org.connector.new_tracker_workload_multi_delete()
143
+ delete_tracker = org.connector.new_tracker_workload_multi_delete() # tracker to handle deletions, it will be executed later
165
144
 
145
+ # Process each duplicated hostname record
166
146
  for dup_hostname, dup_record in duplicated_hostnames._records.items():
167
- if not dup_record.has_duplicates():
147
+
148
+ if not dup_record.has_duplicates(): # no duplicates, skip
168
149
  continue
169
150
 
170
151
  print(" - hostname '{}' has duplicates. ({} online, {} offline, {} unmanaged)".format(dup_hostname,
@@ -172,13 +153,27 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
172
153
  len(dup_record.offline),
173
154
  len(dup_record.unmanaged)))
174
155
 
156
+ # If the new flag was passed, ensure all workloads under this duplicate record have identical labels
157
+ if arg_do_not_delete_if_labels_mismatch:
158
+ label_strings = set()
159
+ for wkl in dup_record.all:
160
+ # Use workload.get_labels_str() to produce a stable representation across label types
161
+ lbl_str = wkl.get_labels_str()
162
+ label_strings.add(lbl_str)
163
+
164
+ if len(label_strings) > 1:
165
+ print(" - IGNORED: workloads for hostname '{}' have mismatching labels".format(dup_hostname))
166
+ for wkl in dup_record.all:
167
+ add_workload_to_report(wkl, "ignored (labels mismatch)")
168
+ continue
169
+
175
170
  if not dup_record.has_no_managed_workloads():
176
171
  latest_created_workload = dup_record.find_latest_managed_created_at()
177
172
  latest_heartbeat_workload = dup_record.find_latest_heartbeat()
178
173
 
179
174
  print(" - Latest created at {} and latest heartbeat at {}".format(latest_created_workload.created_at, latest_heartbeat_workload.ven_agent.get_last_heartbeat_date()))
180
175
 
181
- if dup_record.count_online() == 0:
176
+ if not arg_ignore_pce_online_status and dup_record.count_online() == 0:
182
177
  print(" - IGNORED: there is no VEN online")
183
178
  for wkl in dup_record.offline:
184
179
  add_workload_to_report(wkl, "ignored (no VEN online)")
@@ -188,10 +183,18 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
188
183
  print(" - WARNING: there are more than 1 VEN online")
189
184
 
190
185
  # Don't delete online workloads but still show them in the report
191
- for wkl in dup_record.online:
192
- add_workload_to_report(wkl, "ignored (VEN is online)")
186
+ if not arg_ignore_pce_online_status:
187
+ for wkl in dup_record.online:
188
+ add_workload_to_report(wkl, "ignored (VEN is online)")
189
+
190
+ # Build the list of candidate workloads to consider for deletion. If --ignore-pce-online-status
191
+ # is passed, include online workloads among the candidates.
192
+ if arg_ignore_pce_online_status:
193
+ deletion_candidates = list(dup_record.offline) + list(dup_record.online)
194
+ else:
195
+ deletion_candidates = list(dup_record.offline)
193
196
 
194
- for wkl in dup_record.offline:
197
+ for wkl in deletion_candidates:
195
198
  if arg_do_not_delete_the_most_recent_workload and wkl is latest_created_workload:
196
199
  print(" - IGNORED: wkl {}/{} is the most recent".format(wkl.get_name_stripped_fqdn(), wkl.href))
197
200
  add_workload_to_report(wkl, "ignored (it is the most recently created)")
@@ -207,7 +210,7 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
207
210
  add_workload_to_report(wkl, "ignored (limit of {} workloads to be deleted was reached)".format(arg_limit_number_of_deleted_workloads))
208
211
  else:
209
212
  delete_tracker.add_workload(wkl)
210
- print(" - added offline wkl {}/{} to the delete list".format(wkl.get_name_stripped_fqdn(), wkl.href))
213
+ print(" - added wkl {}/{} to the delete list".format(wkl.get_name_stripped_fqdn(), wkl.href))
211
214
 
212
215
  for wkl in dup_record.unmanaged:
213
216
  if arg_limit_number_of_deleted_workloads is not None and delete_tracker.count_entries() >= arg_limit_number_of_deleted_workloads:
@@ -257,7 +260,8 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
257
260
  for wkl in delete_tracker.workloads:
258
261
  add_workload_to_report(wkl, "TO BE DELETED (aborted by user)")
259
262
  else:
260
- print(" * Executing deletion requests ... ".format(output_file_csv), end='', flush=True)
263
+ # execute deletions
264
+ print(" * Executing deletion requests ... ", end='', flush=True)
261
265
  delete_tracker.execute(unpair_agents=True)
262
266
  print("DONE")
263
267
 
@@ -277,13 +281,29 @@ def __main(args, org: pylo.Organization, pce_cache_was_used: bool, **kwargs):
277
281
  for wkl in delete_tracker.workloads:
278
282
  add_workload_to_report(wkl, "TO BE DELETED (no confirm option used)")
279
283
 
284
+ # if report is not empty, write it to disk
280
285
  if sheet.lines_count() >= 1:
281
286
  if len(report_wanted_format) < 1:
282
287
  print(" * No report format was specified, no report will be generated")
283
288
  else:
284
289
  sheet.reorder_lines(['hostname']) # sort by hostname for better readability
285
290
  for report_format in report_wanted_format:
286
- output_filename = output_file_prefix + '.' + report_format
291
+ # Choose output filename depending on whether user provided --output-filename
292
+ if arg_output_filename is None:
293
+ output_filename = output_file_prefix + '.' + report_format
294
+ else:
295
+ # If only one format requested, use the provided filename as-is
296
+ if len(report_wanted_format) == 1:
297
+ output_filename = arg_output_filename
298
+ else:
299
+ base = os.path.splitext(arg_output_filename)[0]
300
+ output_filename = base + '.' + report_format
301
+
302
+ # Ensure parent directory exists
303
+ output_directory = os.path.dirname(output_filename)
304
+ if output_directory:
305
+ os.makedirs(output_directory, exist_ok=True)
306
+
287
307
  print(" * Writing report file '{}' ... ".format(output_filename), end='', flush=True)
288
308
  if report_format == 'csv':
289
309
  sheet.write_to_csv(output_filename)
@@ -5,6 +5,7 @@ from datetime import datetime
5
5
 
6
6
  import illumio_pylo as pylo
7
7
  from illumio_pylo import ArraysToExcel, ExcelHeader, ExcelHeaderSet
8
+ from illumio_pylo.FilterQuery import FilterQuery, get_workload_filter_registry
8
9
  from .utils.misc import make_filename_with_timestamp
9
10
  from . import Command
10
11
 
@@ -42,6 +43,14 @@ def fill_parser(parser: argparse.ArgumentParser):
42
43
  parser.add_argument('--verbose', '-v', action='store_true',
43
44
  help='')
44
45
 
46
+ parser.add_argument('--filter-query', '-q', type=str, required=False, default=None,
47
+ help='Filter workloads using a SQL-like query expression. '
48
+ 'Supports: ==, !=, <, >, <=, >=, contains, matches (regex), and/or/not, parentheses. '
49
+ 'Available fields: name, hostname, description, online, managed, deleted, '
50
+ 'ip_address, last_heartbeat, mode, env, app, role, loc, os_id, etc. '
51
+ 'Examples: "name contains \'prod\'" or "env == \'Production\' and online == true" '
52
+ 'or "(name == \'srv1\' or name == \'srv2\') and last_heartbeat <= \'2024-01-01\'"')
53
+
45
54
  parser.add_argument('--filter-file', '-i', type=str, required=False, default=None,
46
55
  help='CSV or Excel input filename')
47
56
  parser.add_argument('--filter-file-delimiter', type=str, required=False, default=',',
@@ -60,8 +69,10 @@ def fill_parser(parser: argparse.ArgumentParser):
60
69
  for extra_column in extra_columns:
61
70
  extra_column.apply_cli_args(parser)
62
71
 
72
+
63
73
  def __main(args, org: pylo.Organization, **kwargs):
64
74
 
75
+ filter_query_string = args['filter_query']
65
76
  filter_file = args['filter_file']
66
77
  filter_file_delimiter = args['filter_file_delimiter']
67
78
  filter_fields = args['filter_fields']
@@ -116,6 +127,24 @@ def __main(args, org: pylo.Organization, **kwargs):
116
127
  csv_sheet = csv_report.create_sheet('workloads', csv_report_headers, force_all_wrap_text=True)
117
128
 
118
129
  all_workloads = org.WorkloadStore.itemsByHRef.copy()
130
+
131
+ # Apply filter query if provided
132
+ if filter_query_string is not None:
133
+ print(" * Applying filter query: '{}'".format(filter_query_string))
134
+ try:
135
+ # Pass org to get registry with all configured label types for this PCE
136
+ registry = get_workload_filter_registry(org)
137
+ filter_query = FilterQuery(registry)
138
+
139
+ matching_workloads = filter_query.execute(filter_query_string, list(all_workloads.values()))
140
+
141
+ # Convert back to dict by href
142
+ all_workloads = {w.href: w for w in matching_workloads}
143
+ print(" - Filter query matched {} workload(s)".format(len(all_workloads)))
144
+ except pylo.PyloEx as e:
145
+ pylo.log.error("Filter query error: {}".format(e))
146
+ sys.exit(1)
147
+
119
148
  used_filters = {}
120
149
 
121
150
  def add_workload_to_report(wkl: pylo.Workload = None, filter=None, filter_append_prefix='_'):
@@ -4,7 +4,10 @@ import os
4
4
  import sys
5
5
 
6
6
  # in case user wants to run this utility while having a version of pylo already installed
7
- sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
7
+ if __name__ == "__main__":
8
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
9
+ pass
10
+
8
11
  import illumio_pylo.cli
9
12
 
10
13
  illumio_pylo.cli.run()
@@ -4,7 +4,11 @@ import argparse
4
4
  import math
5
5
  from datetime import datetime
6
6
 
7
- sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
7
+ # in case user wants to run this utility while having a version of pylo already installed
8
+ if __name__ == "__main__":
9
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
10
+ pass
11
+
8
12
  import illumio_pylo as pylo
9
13
 
10
14
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: illumio_pylo
3
- Version: 0.3.11
3
+ Version: 0.3.13
4
4
  Summary: A set of tools and library for working with Illumio PCE
5
5
  Home-page: https://github.com/cpainchaud/pylo
6
6
  Author: Christophe Painchaud
@@ -193,6 +193,7 @@ Requires-Dist: paramiko~=3.4.0
193
193
  Requires-Dist: prettytable~=3.10.0
194
194
  Requires-Dist: requests~=2.32.0
195
195
  Requires-Dist: xlsxwriter~=3.2.0
196
+ Requires-Dist: flask~=2.2.0
196
197
  Dynamic: author
197
198
  Dynamic: author-email
198
199
  Dynamic: description
@@ -1,14 +1,15 @@
1
1
  illumio_pylo/AgentStore.py,sha256=7xWpjGJHK5Xp69M-WzqcDeC1WMLCeMii1D_hh6xVqb4,5312
2
2
  illumio_pylo/Exception.py,sha256=3lxS-ANBaEvHAKhDb8UzNLj5IpQBmRHNs4YkHONmQjs,1033
3
+ illumio_pylo/FilterQuery.py,sha256=AeDCCg8aPR7IXw-Ho09Zng342ZsaMdJVDBuEufcnMeM,32391
3
4
  illumio_pylo/IPList.py,sha256=0fPsX6TYUQmmyWMQpl-QsMll9JwpvEiGN6lmbUtBwDU,4614
4
5
  illumio_pylo/IPMap.py,sha256=XrC-qvnTUWCVq38NCRDebDnXWQYCAyTRtdVX6fk9DiE,10575
5
6
  illumio_pylo/Label.py,sha256=hGeU3zQW8GIfRekSVcRAiTQbezbjYTF1nGHoH9DxvyY,834
6
- illumio_pylo/LabelCommon.py,sha256=fgmzE8tztufAXXzLgmOqo74z66e8uAyJYnM917e8wRE,1486
7
+ illumio_pylo/LabelCommon.py,sha256=TNIVaZ51TyL6XeNE4ShBzp6o7_htWOaUEL1fowpwtos,1930
8
+ illumio_pylo/LabelDimension.py,sha256=Ha0-mxQxfbDmH5aX0IedcsF-QkHJfw6l9kIqbTL8ccM,4427
7
9
  illumio_pylo/LabelGroup.py,sha256=ZPC3xBLJUEhStyBTMB3fTTcEi8Z4CDjHUwnq_T-8p5Y,2674
8
- illumio_pylo/LabelStore.py,sha256=RlkkrJYnA7pdMBs8iTjW0HXGpCOohA0b8aTInarFwrs,19960
10
+ illumio_pylo/LabelStore.py,sha256=t-4JI7AM2K6PHB5DyAt2-BM6oPwrVyFop2rLP4E5K8c,22777
9
11
  illumio_pylo/LabeledObject.py,sha256=uwLDt6dv1Ba1Zd_V3wpgrNtUCS4UilprGhgVbqH2w74,2023
10
12
  illumio_pylo/Organization.py,sha256=eOuMecm8oDsyQNEeHAxsxV9b1T4-6RuEwFRsS6kLcuI,12590
11
- illumio_pylo/Query.py,sha256=lgLjst41ma3HMVkngvTjL7zSLjh80RoXYL5vS3PWO7Q,13330
12
13
  illumio_pylo/ReferenceTracker.py,sha256=X-A6aGnZUkMoEdq17ER4K2YuP0ogg9wnHY786ciHcQg,1012
13
14
  illumio_pylo/Rule.py,sha256=5KE0rLlmG74Kesm5A0At8kvNt2YEwvraKwIdJEEVt4Y,26828
14
15
  illumio_pylo/Ruleset.py,sha256=VCXUqWZrCCzM3uJPWFJpVnKBv6bj0JPz4ydmb-UbSIc,12024
@@ -19,55 +20,59 @@ illumio_pylo/SoftwareVersion.py,sha256=H_5WM42ObUkVtuxVWak30KMbEuar567k33E6pb83Z
19
20
  illumio_pylo/VirtualService.py,sha256=K1GT8pzkMOYkD4ZEwDkdriLOAUFAr0oCYNErJAMy9Ck,617
20
21
  illumio_pylo/VirtualServiceStore.py,sha256=MNTwo1cvteUuID6JniWUk5oRHQHGY4OwrWvFaRXDuuk,3116
21
22
  illumio_pylo/Workload.py,sha256=k6s420rExq_Nb453f9UYjsLyNfxcCGuhgX6sPDBx9kU,19813
22
- illumio_pylo/WorkloadStore.py,sha256=3C6SMU0wRlet6C6UVbjkYNsTY7vkyK_ZwqM1dlCBpsQ,10989
23
+ illumio_pylo/WorkloadStore.py,sha256=SE2fn02uqUtXY3b6r_I8PKocA6ZzDiyp9ToLAAPpfx8,13611
23
24
  illumio_pylo/WorkloadStoreSubClasses.py,sha256=P9dUqT4Hb_tTCW14RmfJU3kVp5Zx9ZcfzeuD2VdsPDs,6101
24
- illumio_pylo/__init__.py,sha256=y8oXd2NUDY3uXSPDEXdEu_pvYPN5ObP1bd5KZoGNcXU,4173
25
+ illumio_pylo/__init__.py,sha256=hC61scY-eb8k7XooRK5VTMjM2bnic8nguI7hFKeDkbI,4598
25
26
  illumio_pylo/tmp.py,sha256=8WSnsdgnLgVS2m4lxc6qCpCfefADV77B8MqiwdqFkos,3914
26
- illumio_pylo/API/APIConnector.py,sha256=pHwwwthjzYa27fVnobs4D3ZwRnDq3amD6JjJ9L1gTXM,64919
27
+ illumio_pylo/API/APIConnector.py,sha256=bZkysEA53-Rac6Wn-1Hyfry9pVBnOM_JbN8dcJBNBx4,67025
27
28
  illumio_pylo/API/AuditLog.py,sha256=p0mfjrE5S8qoJgA5LIP_XGFBP3iL86Nl6BQEmhMVrPA,1533
28
29
  illumio_pylo/API/ClusterHealth.py,sha256=GdMpVQrHUW4zLM-409GcPHM8H8b3LAppO37ZcUZyT_Q,5122
29
- illumio_pylo/API/CredentialsManager.py,sha256=z-a8O67UwPnbAEmjv_t8C9Wb0eXbSql1PVhLZ8IEUms,12854
30
- illumio_pylo/API/Explorer.py,sha256=fZQDkjbbJTYYOAuVqsbb7STJDNKFVj2U5LsF4yQN6TE,49201
31
- illumio_pylo/API/JsonPayloadTypes.py,sha256=wrKMW3xSTM-PQk6ABUI4lNu-HAQMtnfaZ6FjGA1yypw,8963
30
+ illumio_pylo/API/CredentialsManager.py,sha256=0MN8zsGTYR73YV0gx7HXF2t4kQ5bdS9Unp96KQe7h-c,19745
31
+ illumio_pylo/API/Explorer.py,sha256=0BveCODg8s1OCg3c-5ECiiRz-1O-EVec3DXj4CcwBS4,75029
32
+ illumio_pylo/API/JsonPayloadTypes.py,sha256=j4_EIJHGNj-vcj7Z-DBuzVQb6DXVk5FLOKwXa-SrjRc,10737
32
33
  illumio_pylo/API/RuleSearchQuery.py,sha256=O0-MsUXhwmywoO0G-GXnLq6kkVC9LgmxMZwqVKc_oJE,5325
33
34
  illumio_pylo/API/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
35
  illumio_pylo/Helpers/__init__.py,sha256=6E2eTZe-4qfPKGjRRQNtYsPrBhJSAjbdvv_DpniV_rY,49
35
- illumio_pylo/Helpers/exports.py,sha256=7wXWTRmjkfApgeweJ3gJ4qUXJLOK0xyA49cY_EkkkCg,21898
36
+ illumio_pylo/Helpers/exports.py,sha256=3lme5g1UZYSlEkvfT3gU5dj86ndX0NIGQVFsAw2nZWQ,21896
36
37
  illumio_pylo/Helpers/functions.py,sha256=WmLCJjAHPLqJH6WM7bKSz4ZbP2zDAFJ73FCoJZRTIJE,4635
37
38
  illumio_pylo/cli/NativeParsers.py,sha256=nzDL54EV0J-Iz0P9EkeiPl6DWQBSbCu-MpEPRad3j6c,4055
38
- illumio_pylo/cli/__init__.py,sha256=hgp7KG4FZujnRnId3A1tAoaYpUDFkE_Fv2wXyF02GNM,7737
39
+ illumio_pylo/cli/__init__.py,sha256=HKhEI78i4byW_RjVzJK9EZEEY5_cBZm586DV6-ePl5w,8075
39
40
  illumio_pylo/cli/__main__.py,sha256=ll1gK8k1YL_kPsImI7WVlw2sCyNyhocnuCqko6mGaYI,223
40
- illumio_pylo/cli/commands/__init__.py,sha256=_M2qTOOfCN3FVnL_0j6CgfwYmatvobzwierJDtlVtz0,1537
41
- illumio_pylo/cli/commands/credential_manager.py,sha256=YUaIqTxl9F7HXpxC7urU2tnwZq3UROV4riV_YMKSJso,9354
41
+ illumio_pylo/cli/commands/__init__.py,sha256=hbPDoNFm55hHtEUq5lLloGq6nJxDkjNbw4hZIAXwdJc,1580
42
+ illumio_pylo/cli/commands/credential_manager.py,sha256=x6NmKs3gSC2yD_-Uy853s7r6PYzjSJjEpOKntIcsTac,35639
42
43
  illumio_pylo/cli/commands/iplist_analyzer.py,sha256=OJB8hSDzLhICCkFF5NaRC3a0uCUSfaEDuJb2CLUJgu4,3709
43
44
  illumio_pylo/cli/commands/iplist_import_from_file.py,sha256=yqB6VvDT72VxC8tIyu2wRixorwzarhWF6t8J-MvLGlM,9836
44
- illumio_pylo/cli/commands/label_delete_unused.py,sha256=xrMBi1cJcoAbgbGVxkoqGnHUJoM2WMsPzUQ_r4do-eg,3490
45
+ illumio_pylo/cli/commands/label_delete_unused.py,sha256=KRJDppSQFonKVet9kjrPOaHUiIhahfjHMs92KAE9mYQ,3434
45
46
  illumio_pylo/cli/commands/ruleset_export.py,sha256=MsT-jd0BzA_cpZcvbKtkD1Dvwqt6_9F5Q1vp8-qfEo0,6080
46
- illumio_pylo/cli/commands/update_pce_objects_cache.py,sha256=vSVSA9K9mXQhfiQPLoH7uEcSz5j1JddQW6UGGYvydKQ,1255
47
+ illumio_pylo/cli/commands/traffic_export.py,sha256=MvNad_gGtawDg9Hqdv-VhJAv7s6ejh8EjCpw1nZNQSo,19219
48
+ illumio_pylo/cli/commands/update_pce_objects_cache.py,sha256=r6zOpSezO2IV1MF2R3EABnE5UTqkuF2tof5I7OGHRJg,1168
47
49
  illumio_pylo/cli/commands/ven_compatibility_report_export.py,sha256=Hp58Z0cj-hX8tpcD9IyT0c2c36CutT9rrfhTfgx9sbI,8070
48
- illumio_pylo/cli/commands/ven_duplicate_remover.py,sha256=0QISvVCShJPDEQeB0RLE9EGEcVzHHt5rl8tYmsAXd6k,21837
50
+ illumio_pylo/cli/commands/ven_duplicate_remover.py,sha256=zPLbuZ3m2sFP6IbeZeUGM3R63K-ih8Db3C6H-JSqPNo,23397
49
51
  illumio_pylo/cli/commands/ven_idle_to_visibility.py,sha256=ez8NbryK_I7motzkhLWHOdKl0Uh-zCkO4ASD1exsOkY,13352
50
52
  illumio_pylo/cli/commands/ven_upgrader.py,sha256=h0XCcI-kMzq9GC-ovIph7r0-BObo_4GHdyuMnVfRYZA,7158
51
- illumio_pylo/cli/commands/workload_export.py,sha256=EcQR8AacJVe7rOqYH-HFxyTchwHHQ9ZTc-ALSMt9gDY,11421
53
+ illumio_pylo/cli/commands/workload_export.py,sha256=f0R9QVBnC45VI8rfh8pkkPNvHDD--6GN94z_dHanqto,13052
52
54
  illumio_pylo/cli/commands/workload_import.py,sha256=mpcHISn5qxM13eSYCWusQRvkkNuZ0bnrrOBfZE2s1R8,19024
53
55
  illumio_pylo/cli/commands/workload_reset_names_to_null.py,sha256=j87jbnDxT3kABlqCHlqVd1_U1mfV7y0mgFwEEdFmt0Q,3331
54
56
  illumio_pylo/cli/commands/workload_update.py,sha256=nPlSCOAx0wmshVWy4WNp-15wwg-IWcPPQy66AWEDTic,28659
55
57
  illumio_pylo/cli/commands/workload_used_in_rule_finder.py,sha256=35t_HpAw_gk9SjmNoyPI3eyZT6doPhqcFF6XkuzbNII,3340
58
+ illumio_pylo/cli/commands/ui/credential_manager_ui/app.js,sha256=eX_TT57w9P4dgtlmUl64F-LzOvHdP87pItxk_LLxSpo,25948
59
+ illumio_pylo/cli/commands/ui/credential_manager_ui/index.html,sha256=IsXslEHZpd17hk63I043LuwAVV9qJGIqJVNdqeOnAFY,10231
60
+ illumio_pylo/cli/commands/ui/credential_manager_ui/styles.css,sha256=3aemQRNquY2swElMyVwNDHF0CYwd5CAZ970njz7RSdM,10504
56
61
  illumio_pylo/cli/commands/utils/LabelCreation.py,sha256=cO_MWJrAIgeZGZrm0Dix50isrGzhckZ_kLnjy1VWWRI,4885
57
62
  illumio_pylo/cli/commands/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
63
  illumio_pylo/cli/commands/utils/misc.py,sha256=dsFHrmCaQ1OrRGms8dHaHtE_rTJ0j4-Q3JXcFCKNC_I,775
59
64
  illumio_pylo/docs/Doxygen,sha256=AVvSIRYLHFWJ15YLGahhzhsW0ZUUFO5lVxd2-F3iWz8,74257
60
65
  illumio_pylo/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- illumio_pylo/utilities/cli.py,sha256=7Wv7qhdc91-vsaxiu4j8k7LY7V9dcwWHnHV7PLpOBAI,320
66
+ illumio_pylo/utilities/cli.py,sha256=AJl9NaMzAfKbEHwVy96bvXAZMV_jdcwvpUodWEEgoDQ,361
62
67
  illumio_pylo/utilities/credentials.example.json,sha256=CZcp3aAbdVljfyQzFbgxIZCU9Ln2eWZKfWcmN9VAeVc,439
63
- illumio_pylo/utilities/health_monitoring.py,sha256=sqe9gArMZm3s8y6Jg6F9SO_Rm2dj1aM99xpPi8WSFZc,3700
68
+ illumio_pylo/utilities/health_monitoring.py,sha256=_8IsDvOGxoqMvZhN8GQwHqrRb5qkh_x4ccENuECe19E,3831
64
69
  illumio_pylo/utilities/resources/iplists-import-example.csv,sha256=beM9OBWJQNiYXlGh1KYiHxCN8LpZk4uPpoiO14-CgOE,200
65
70
  illumio_pylo/utilities/resources/iplists-import-example.xlsx,sha256=VW-7CRr8NA2Vultv9jLGd8-_jzVp5ZtL3KgswjOUHeQ,16893
66
71
  illumio_pylo/utilities/resources/workload-exporter-filter-example.csv,sha256=cn5IA8AGEPjvS-EsPXA_GJ-LFsdF9t_44rSzFTCmAzE,36
67
72
  illumio_pylo/utilities/resources/workloads-import-example.csv,sha256=HBZj5e1TFnJTzNrcgO3ZVzqAwqBoyGABJtd9Y8W8j7g,115
68
73
  illumio_pylo/utilities/resources/workloads-import-example.xlsx,sha256=B5LRCFjqkZ0xbGel7qlmLepmhAysoq1Cu9eVFUiZLq0,17191
69
- illumio_pylo-0.3.11.dist-info/licenses/LICENSE,sha256=WYmcYJG1QFgu1hfo7qrEkZ3Jhcz8NUWe6XUraZvlIFs,10172
70
- illumio_pylo-0.3.11.dist-info/METADATA,sha256=qkdSIEc2zWi5HvmUzPi3xU2MU1nqTg3ZgMiKlARJBaQ,12375
71
- illumio_pylo-0.3.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
72
- illumio_pylo-0.3.11.dist-info/top_level.txt,sha256=c5cu_ZMuSuxjq48ih58Kc0Tr8-JdQtV8GrKJicvWNFE,13
73
- illumio_pylo-0.3.11.dist-info/RECORD,,
74
+ illumio_pylo-0.3.13.dist-info/licenses/LICENSE,sha256=WYmcYJG1QFgu1hfo7qrEkZ3Jhcz8NUWe6XUraZvlIFs,10172
75
+ illumio_pylo-0.3.13.dist-info/METADATA,sha256=qD7_8UV-sKxlflovdH-Hpxo0EBLGKMzffutfeLS8ILQ,12403
76
+ illumio_pylo-0.3.13.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
77
+ illumio_pylo-0.3.13.dist-info/top_level.txt,sha256=c5cu_ZMuSuxjq48ih58Kc0Tr8-JdQtV8GrKJicvWNFE,13
78
+ illumio_pylo-0.3.13.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5