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,240 @@
1
+ import os
2
+ import sys
3
+ import argparse
4
+ from datetime import datetime
5
+
6
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
7
+ import illumio_pylo as pylo
8
+
9
+
10
+ parser = argparse.ArgumentParser(description='Get compatibility reports from all your IDLE VEN so you can review and remediate them')
11
+ parser.add_argument('--pce', type=str, required=True,
12
+ help='hostname of the PCE')
13
+
14
+ parser.add_argument('--dev-use-cache', type=bool, nargs='?', required=False, default=False, const=True,
15
+ help='For developers only')
16
+
17
+ parser.add_argument('--filter-env-label', type=str, required=False, default=None,
18
+ help='Filter agents by environment labels (separated by commas)')
19
+ parser.add_argument('--filter-loc-label', type=str, required=False, default=None,
20
+ help='Filter agents by environment labels (separated by commas)')
21
+ parser.add_argument('--filter-app-label', type=str, required=False, default=None,
22
+ help='Filter agents by role labels (separated by commas)')
23
+ parser.add_argument('--filter-role-label', type=str, required=False, default=None,
24
+ help='Filter agents by role labels (separated by commas)')
25
+
26
+
27
+ parser.add_argument('--debug', type=bool, nargs='?', required=False, default=False, const=True,
28
+ help='extra debugging messages')
29
+
30
+ args = vars(parser.parse_args())
31
+
32
+ if args['debug']:
33
+ pylo.log_set_debug()
34
+
35
+
36
+ hostname = args['pce']
37
+ use_cached_config = args['dev_use_cache']
38
+ now = datetime.now()
39
+ output_filename_csv = 'compatibility-reports_{}.csv'.format(now.strftime("%Y%m%d-%H%M%S"))
40
+ output_filename_xls = 'compatibility-reports_{}.xlsx'.format(now.strftime("%Y%m%d-%H%M%S"))
41
+
42
+
43
+ pylo.file_clean(output_filename_csv)
44
+ pylo.file_clean(output_filename_xls)
45
+
46
+
47
+ minimum_supported_version = pylo.SoftwareVersion("18.2.0-0")
48
+
49
+ org = pylo.Organization(1)
50
+ fake_config = pylo.Organization.create_fake_empty_config()
51
+
52
+ if use_cached_config:
53
+ org.load_from_cache_or_saved_credentials(hostname)
54
+ else:
55
+ print(" * Looking for credentials for PCE '{}'... ".format(hostname), end="", flush=True)
56
+ connector = pylo.APIConnector.create_from_credentials_in_file(hostname, request_if_missing=True)
57
+ print("OK!")
58
+
59
+ print(" * Downloading Workloads/Agents listing from the PCE... ", end="", flush=True)
60
+ fake_config['workloads'] = connector.objects_workload_get()
61
+ print("OK!")
62
+
63
+ print(" * Downloading Labels listing from the PCE... ", end="", flush=True)
64
+ fake_config['labels'] = connector.objects_label_get()
65
+ print("OK!")
66
+
67
+ print(" * Parsing PCE data ... ", end="", flush=True)
68
+ org.pce_version = connector.version
69
+ org.load_from_json(fake_config)
70
+ print("OK!")
71
+
72
+ print(" * PCE data statistics:\n{}".format(org.stats_to_str(padding=' ')))
73
+
74
+ agents = {}
75
+ for agent in org.AgentStore.items_by_href.values():
76
+ if agent.mode == 'idle':
77
+ agents[agent.href] = agent
78
+ print(" * Found {} IDLE Agents".format(len(agents)))
79
+
80
+ print(" * Parsing filters")
81
+
82
+ env_label_list = {}
83
+ if args['filter_env_label'] is not None:
84
+ print(" * Environment Labels specified")
85
+ for raw_label_name in args['filter_env_label'].split(','):
86
+ print(" - label named '{}'".format(raw_label_name), end='', flush=True)
87
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_env)
88
+ if label is None:
89
+ print("NOT FOUND!")
90
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
91
+ else:
92
+ print(" FOUND")
93
+ env_label_list[label] = label
94
+
95
+ loc_label_list = {}
96
+ if args['filter_loc_label'] is not None:
97
+ print(" * Location Labels specified")
98
+ for raw_label_name in args['filter_loc_label'].split(','):
99
+ print(" - label named '{}' ".format(raw_label_name), end='', flush=True)
100
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_loc)
101
+ if label is None:
102
+ print("NOT FOUND!")
103
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
104
+ else:
105
+ print("FOUND")
106
+ loc_label_list[label] = label
107
+
108
+ app_label_list = {}
109
+ if args['filter_app_label'] is not None:
110
+ print(" * Application Labels specified")
111
+ for raw_label_name in args['filter_app_label'].split(','):
112
+ print(" - label named '{}' ".format(raw_label_name), end='', flush=True)
113
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_app)
114
+ if label is None:
115
+ print("NOT FOUND!")
116
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
117
+ else:
118
+ print("FOUND")
119
+ app_label_list[label] = label
120
+
121
+ role_label_list = {}
122
+ if args['filter_role_label'] is not None:
123
+ print(" * Role Labels specified")
124
+ for raw_label_name in args['filter_role_label'].split(','):
125
+ print(" - label named '{}' ".format(raw_label_name), end='', flush=True)
126
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_role)
127
+ if label is None:
128
+ print("NOT FOUND!")
129
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
130
+ else:
131
+ print("FOUND")
132
+ role_label_list[label] = label
133
+
134
+
135
+ print(" * Applying filters to the list of Agents...", flush=True, end='')
136
+
137
+ for agent_href in list(agents.keys()):
138
+ agent = agents[agent_href]
139
+ workload = agent.workload
140
+
141
+ if len(env_label_list) > 0 and (workload.env_label is None or workload.env_label not in env_label_list):
142
+ del agents[agent_href]
143
+ continue
144
+ if len(loc_label_list) > 0 and (workload.loc_label is None or workload.loc_label not in loc_label_list):
145
+ del agents[agent_href]
146
+ continue
147
+ if len(app_label_list) > 0 and (workload.app_label is None or workload.app_label not in app_label_list):
148
+ del agents[agent_href]
149
+ continue
150
+
151
+ if len(role_label_list) > 0 and (workload.role_label is None or workload.role_label not in role_label_list):
152
+ del agents[agent_href]
153
+ continue
154
+ print("OK!")
155
+
156
+ print()
157
+ print(" ** Request Compatibility Report for each Agent in IDLE mode **", flush=True)
158
+
159
+ agent_count = 0
160
+ agent_green_count = 0
161
+ agent_mode_changed_count = 0
162
+ agent_skipped_not_online = 0
163
+ agent_has_no_report_count = 0
164
+ agent_report_failed_count = 0
165
+
166
+ export_report = pylo.Helpers.ArrayToExport(['hostname', 'role', 'app', 'env', 'loc', 'operating_system', 'report_failed', 'details', 'href'])
167
+
168
+ for agent in agents.values():
169
+ agent_count += 1
170
+ export_row = []
171
+ print(" - Agent #{}/{}: wkl NAME:'{}' HREF:{} Labels:{}".format(agent_count, len(agents), agent.workload.get_name(),
172
+ agent.workload.href,
173
+ agent.workload.get_labels_str())
174
+ )
175
+ if not agent.workload.online:
176
+ print(" - Agent is not ONLINE so we're skipping it")
177
+ agent_skipped_not_online += 1
178
+ continue
179
+
180
+ export_row.append(agent.workload.get_name())
181
+ labels = agent.workload.get_labels_str_list()
182
+ export_row.append(labels[0])
183
+ export_row.append(labels[1])
184
+ export_row.append(labels[2])
185
+ export_row.append(labels[3])
186
+ export_row.append(agent.workload.os_id)
187
+
188
+ print(" - Downloading report...", flush=True, end='')
189
+ report = connector.agent_get_compatibility_report(agent_href=agent.href, return_raw_json=False)
190
+ print('OK')
191
+
192
+ if report.empty:
193
+ print(" - Report does not exist")
194
+ agent_has_no_report_count += 1
195
+ export_row.append('not-available')
196
+ export_row.append('')
197
+ else:
198
+ print(" - Report status is '{}'".format(report.global_status))
199
+ if report.global_status == 'green':
200
+ agent_green_count += 1
201
+ export_row.append('no')
202
+ export_row.append('')
203
+ else:
204
+ export_row.append('yes')
205
+ failed_items_texts = []
206
+ for failed_item in report.get_failed_items().values():
207
+ if failed_item.extra_debug_message is None:
208
+ failed_items_texts.append(failed_item.name)
209
+ else:
210
+ failed_items_texts.append('{}({})'.format(failed_item.name, failed_item.extra_debug_message))
211
+ failed_items = pylo.string_list_to_text(failed_items_texts)
212
+ agent_report_failed_count += 1
213
+ export_row.append(failed_items)
214
+
215
+ export_row.append(agent.workload.href)
216
+
217
+ export_report.add_line_from_list(export_row)
218
+
219
+
220
+ print("\n**** Saving Compatibility Reports to '{}' ****".format(output_filename_csv), end='', flush=True)
221
+ export_report.write_to_csv(output_filename_csv)
222
+ print("OK!")
223
+ print("\n**** Saving Compatibility Reports to '{}' ****".format(output_filename_xls), end='', flush=True)
224
+ export_report.write_to_excel(output_filename_xls, 'Workloads')
225
+ print("OK!")
226
+
227
+
228
+ def myformat(name, value):
229
+ return "{:<42} {:>6}".format(name, value)
230
+ # return "{:<18} {:>6}".format(name, "${:.2f}".format(value))
231
+
232
+
233
+ print("\n\n*** Statistics ***")
234
+ print(myformat(" - IDLE Agents count:", agent_count))
235
+ print(myformat(" - Agents with successful report count:", agent_green_count))
236
+ print(myformat(" - SKIPPED because not online count:", agent_skipped_not_online))
237
+ print(myformat(" - SKIPPED because report was not found:", agent_has_no_report_count))
238
+ print(myformat(" - Agents with failed reports:", agent_report_failed_count ))
239
+
240
+ print()
@@ -0,0 +1,344 @@
1
+ import os
2
+ import sys
3
+ import argparse
4
+ from datetime import datetime
5
+ from typing import Union,Dict,List
6
+
7
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
8
+ import illumio_pylo as pylo
9
+
10
+
11
+ parser = argparse.ArgumentParser(description='TODO LATER')
12
+ parser.add_argument('--pce', type=str, required=True,
13
+ help='hostname of the PCE')
14
+
15
+ parser.add_argument('--dev-use-cache', type=bool, nargs='?', required=False, default=False, const=True,
16
+ help='For developers only')
17
+
18
+ parser.add_argument('--filter-env-label', type=str, required=False, default=None,
19
+ help='Filter agents by environment labels (separated by commas)')
20
+ parser.add_argument('--filter-loc-label', type=str, required=False, default=None,
21
+ help='Filter agents by environment labels (separated by commas)')
22
+ parser.add_argument('--filter-app-label', type=str, required=False, default=None,
23
+ help='Filter agents by role labels (separated by commas)')
24
+ parser.add_argument('--filter-role-label', type=str, required=False, default=None,
25
+ help='Filter agents by role labels (separated by commas)')
26
+
27
+ parser.add_argument('--filter-on-href-from-file', type=str, required=False, default=None,
28
+ help='Filter agents on workload href found in specific csv file')
29
+
30
+ parser.add_argument('--ignore-incompatibilities', type=str, nargs='+', required=False, default=None,
31
+ help="Ignore specific incompatibilities and force mode switch!")
32
+
33
+ parser.add_argument('--ignore-all-incompatibilities', action='store_true',
34
+ help="Don't check compatibility report and just do the change!")
35
+
36
+
37
+ parser.add_argument('--confirm', action='store_true',
38
+ help='Request upgrade of the Agents')
39
+
40
+ parser.add_argument('--debug', type=bool, nargs='?', required=False, default=False, const=True,
41
+ help='extra debugging messages')
42
+
43
+ parser.add_argument('--mode', type=str.lower, required=True, choices=['build', 'test'],
44
+ help='Select if you want to switch from IDLE to BUILD or TEST')
45
+
46
+
47
+ args = vars(parser.parse_args())
48
+
49
+ if args['debug']:
50
+ pylo.log_set_debug()
51
+
52
+
53
+ hostname = args['pce']
54
+ print(args)
55
+ use_cached_config = args['dev_use_cache']
56
+ request_upgrades = args['confirm']
57
+ switch_to_mode = args['mode']
58
+ href_filter_file = args['filter_on_href_from_file']
59
+ options_ignore_all_incompatibilities = args['ignore_all_incompatibilities']
60
+ option_ignore_incompatibilities: Union[None, Dict[str, bool]] = None
61
+ if args['ignore_incompatibilities'] is not None:
62
+ option_ignore_incompatibilities = {}
63
+ for entry in args['ignore_incompatibilities']:
64
+ option_ignore_incompatibilities[entry] = True
65
+
66
+
67
+ minimum_supported_version = pylo.SoftwareVersion("18.2.0-0")
68
+
69
+ org = pylo.Organization(1)
70
+ fake_config = pylo.Organization.create_fake_empty_config()
71
+
72
+ now = datetime.now()
73
+ report_file = 'ven-idle-to-illumination-results_{}.csv'.format(now.strftime("%Y%m%d-%H%M%S"))
74
+ report_file_excel = 'ven-idle-to-illumination-results_{}.xlsx'.format(now.strftime("%Y%m%d-%H%M%S"))
75
+
76
+ csv_report_headers = ['name', 'hostname', 'role', 'app', 'env', 'loc', 'changed_mode', 'details', 'href']
77
+ csv_report = pylo.ArrayToExport(csv_report_headers)
78
+
79
+
80
+ def add_workload_to_report(wkl: pylo.Workload, changed_mode: str, details: str):
81
+ labels = workload.get_labels_str_list()
82
+ new_row = {
83
+ 'hostname': wkl.hostname,
84
+ 'role': labels[0],
85
+ 'app': labels[1],
86
+ 'env': labels[2],
87
+ 'loc': labels[3],
88
+ 'href': wkl.href,
89
+ 'status': wkl.get_status_string(),
90
+ 'changed_mode': changed_mode,
91
+ 'details': details
92
+ }
93
+
94
+ csv_report.add_line_from_object(new_row)
95
+
96
+
97
+ if use_cached_config:
98
+ org.load_from_cache_or_saved_credentials(hostname)
99
+ else:
100
+ print(" * Looking for credentials for PCE '{}'... ".format(hostname), end="", flush=True)
101
+ connector = pylo.APIConnector.create_from_credentials_in_file(hostname, request_if_missing=True)
102
+ print("OK!")
103
+
104
+ print(" * Downloading Workloads/Agents listing from the PCE... ", end="", flush=True)
105
+ fake_config['workloads'] = connector.objects_workload_get()
106
+ print("OK!")
107
+
108
+ print(" * Downloading Labels listing from the PCE... ", end="", flush=True)
109
+ fake_config['labels'] = connector.objects_label_get()
110
+ print("OK!")
111
+
112
+ print(" * Parsing PCE data ... ", end="", flush=True)
113
+ org.pce_version = connector.version
114
+ org.load_from_json(fake_config)
115
+ print("OK!")
116
+
117
+ print(" * PCE data statistics:\n{}".format(org.stats_to_str(padding=' ')))
118
+
119
+ href_filter_data = None
120
+ if href_filter_file is not None:
121
+ print(" * Loading CSV input file '{}'...".format(href_filter_file), flush=True, end='')
122
+ href_filter_data = pylo.CsvExcelToObject(href_filter_file, expected_headers=[{'name': 'href', 'optional': False}])
123
+ print('OK')
124
+ print(" - CSV has {} columns and {} lines (headers don't count)".format(href_filter_data.count_columns(), href_filter_data.count_lines()), flush=True)
125
+
126
+ agents = {}
127
+ for agent in org.AgentStore.items_by_href.values():
128
+ if agent.mode == 'idle':
129
+ agents[agent.href] = agent
130
+ print(" * Found {} IDLE Agents".format(len(agents)))
131
+ count_idle_agents_total = len(agents)
132
+
133
+ print(" * Parsing filters")
134
+
135
+ env_label_list = {}
136
+ if args['filter_env_label'] is not None:
137
+ print(" * Environment Labels specified")
138
+ for raw_label_name in args['filter_env_label'].split(','):
139
+ print(" - label named '{}'".format(raw_label_name), end='', flush=True)
140
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_env)
141
+ if label is None:
142
+ print("NOT FOUND!")
143
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
144
+ else:
145
+ print(" found")
146
+ env_label_list[label] = label
147
+
148
+ loc_label_list = {}
149
+ if args['filter_loc_label'] is not None:
150
+ print(" * Location Labels specified")
151
+ for raw_label_name in args['filter_loc_label'].split(','):
152
+ print(" - label named '{}' ".format(raw_label_name), end='', flush=True)
153
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_loc)
154
+ if label is None:
155
+ print("NOT FOUND!")
156
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
157
+ else:
158
+ print(" found")
159
+ loc_label_list[label] = label
160
+
161
+ app_label_list = {}
162
+ if args['filter_app_label'] is not None:
163
+ print(" * Application Labels specified")
164
+ for raw_label_name in args['filter_app_label'].split(','):
165
+ print(" - label named '{}' ".format(raw_label_name), end='', flush=True)
166
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_app)
167
+ if label is None:
168
+ print(" NOT FOUND!")
169
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
170
+ else:
171
+ print(" found")
172
+ app_label_list[label] = label
173
+
174
+ role_label_list = {}
175
+ if args['filter_role_label'] is not None:
176
+ print(" * Role Labels specified")
177
+ for raw_label_name in args['filter_role_label'].split(','):
178
+ print(" - label named '{}' ".format(raw_label_name), end='', flush=True)
179
+ label = org.LabelStore.find_label_by_name_and_type(raw_label_name, pylo.label_type_role)
180
+ if label is None:
181
+ print("NOT FOUND!")
182
+ raise pylo.PyloEx("Cannot find label named '{}'".format(raw_label_name))
183
+ else:
184
+ print("found")
185
+ role_label_list[label] = label
186
+ print(" * DONE")
187
+
188
+ print(" * Applying filters to the list of Agents...", flush=True, end='')
189
+
190
+ for agent_href in list(agents.keys()):
191
+ agent = agents[agent_href]
192
+ workload = agent.workload
193
+
194
+ if len(env_label_list) > 0 and (workload.env_label is None or workload.env_label not in env_label_list):
195
+ del agents[agent_href]
196
+ continue
197
+ if len(loc_label_list) > 0 and (workload.loc_label is None or workload.loc_label not in loc_label_list):
198
+ del agents[agent_href]
199
+ continue
200
+ if len(app_label_list) > 0 and (workload.app_label is None or workload.app_label not in app_label_list):
201
+ del agents[agent_href]
202
+ continue
203
+ if len(role_label_list) > 0 and (workload.role_label is None or workload.role_label not in role_label_list):
204
+ del agents[agent_href]
205
+ continue
206
+
207
+ if href_filter_data is not None:
208
+ workload_href_found = False
209
+ for href_entry in href_filter_data.objects():
210
+ workload_href = href_entry['href']
211
+ if workload_href is not None and workload_href == workload.href:
212
+ workload_href_found = True
213
+ break
214
+ if not workload_href_found:
215
+ del agents[agent_href]
216
+ continue
217
+
218
+
219
+ print("OK! {} VENs are matching filters (from initial list of {} IDLE VENs).".format(len(agents), count_idle_agents_total))
220
+
221
+ print()
222
+ print(" ** Request Compatibility Report for each Agent in IDLE mode **")
223
+
224
+ agent_count = 0
225
+ agent_green_count = 0
226
+ agent_mode_changed_count = 0
227
+ agent_skipped_not_online = 0
228
+ agent_has_no_report_count = 0
229
+ agent_report_failed_count = 0
230
+
231
+ try:
232
+ for agent in agents.values():
233
+ agent_count += 1
234
+ print(" - Agent #{}/{}: wkl NAME:'{}' HREF:{} Labels:{}".format(agent_count, len(agents), agent.workload.get_name(),
235
+ agent.workload.href,
236
+ agent.workload.get_labels_str())
237
+ )
238
+ if not agent.workload.online:
239
+ print(" - Agent is not ONLINE so we're skipping it")
240
+ agent_skipped_not_online += 1
241
+ add_workload_to_report(agent.workload, 'no', 'VEN is not online')
242
+ continue
243
+
244
+ if options_ignore_all_incompatibilities:
245
+ if not request_upgrades:
246
+ print(" - ** SKIPPING Agent mode change process as option '--confirm' was not used")
247
+ add_workload_to_report(agent.workload, 'no', '--confirm option was not used')
248
+ continue
249
+ print(" - Request Agent mode switch to BUILD/TEST...", end='', flush=True)
250
+ connector.objects_agent_change_mode(agent.workload.href, switch_to_mode)
251
+ print("OK")
252
+ agent_mode_changed_count += 1
253
+ add_workload_to_report(agent.workload, 'yes', '')
254
+ continue
255
+
256
+ print(" - Downloading report...", flush=True, end='')
257
+ report = connector.agent_get_compatibility_report(agent_href=agent.href, return_raw_json=False)
258
+ print('OK')
259
+ if report.empty:
260
+ print(" - ** SKIPPING : Report does not exist")
261
+ agent_has_no_report_count += 1
262
+ add_workload_to_report(agent.workload, 'no', 'Compatibility report does not exist')
263
+ continue
264
+ print(" - Report status is '{}'".format(report.global_status))
265
+ if report.global_status == 'green':
266
+ agent_green_count += 1
267
+ if not request_upgrades:
268
+ print(" - ** SKIPPING Agent mode change process as option '--confirm' was not used")
269
+ add_workload_to_report(agent.workload, 'no', '--confirm option was not used')
270
+ continue
271
+ print(" - Request Agent mode switch to BUILD/TEST...", end='', flush=True)
272
+ connector.objects_agent_change_mode(agent.workload.href, switch_to_mode)
273
+ print("OK")
274
+ agent_mode_changed_count += 1
275
+ add_workload_to_report(agent.workload, 'yes', '')
276
+ else:
277
+ print(" - the following issues were found in the report:", flush=True)
278
+ failed_items = report.get_failed_items()
279
+ issues_remaining = False
280
+ for failed_item in failed_items:
281
+ if option_ignore_incompatibilities is not None and failed_item in option_ignore_incompatibilities:
282
+ print(" -{} (ignored because it's part of --ignore-incompatibilities list)".format(failed_item))
283
+ else:
284
+ print(" -{}".format(failed_item))
285
+ issues_remaining = True
286
+
287
+ if not issues_remaining:
288
+ agent_green_count += 1
289
+ if not request_upgrades:
290
+ print(" - ** SKIPPING Agent mode change process as option '--confirm' was not used")
291
+ add_workload_to_report(agent.workload, 'no', '--confirm option was not used')
292
+ continue
293
+ print(" - Request Agent mode switch to BUILD/TEST...", end='', flush=True)
294
+ connector.objects_agent_change_mode(agent.workload.href, switch_to_mode)
295
+ print("OK")
296
+ agent_mode_changed_count += 1
297
+ add_workload_to_report(agent.workload, 'yes', '')
298
+ continue
299
+
300
+ add_workload_to_report(agent.workload, 'no',
301
+ 'compatibility report has reported issues: {}'.format(pylo.string_list_to_text(failed_items.keys()))
302
+ )
303
+ agent_report_failed_count += 1
304
+
305
+ except:
306
+ pylo.log.error("An unexpected error happened, an intermediate report will be written and original traceback displayed")
307
+ pylo.log.error(" * Writing report file '{}' ... ".format(report_file))
308
+ csv_report.write_to_csv(report_file)
309
+ pylo.log.error("DONE")
310
+ pylo.log.error(" * Writing report file '{}' ... ".format(report_file_excel))
311
+ csv_report.write_to_excel(report_file_excel)
312
+ pylo.log.error("DONE")
313
+
314
+ raise
315
+
316
+
317
+ def myformat(name, value):
318
+ return "{:<42} {:>6}".format(name, value)
319
+ # return "{:<18} {:>6}".format(name, "${:.2f}".format(value))
320
+
321
+
322
+ print("\n\n*** Statistics ***")
323
+ print(myformat(" - IDLE Agents count (after filters):", agent_count))
324
+ if request_upgrades:
325
+ print(myformat(" - Agents mode changed count:", agent_mode_changed_count))
326
+ else:
327
+ print(myformat(" - Agents with successful report count:", agent_green_count))
328
+ print(myformat(" - SKIPPED because not online count:", agent_skipped_not_online))
329
+ print(myformat(" - SKIPPED because report was not found:", agent_has_no_report_count))
330
+ print(myformat(" - Agents with failed reports:", agent_report_failed_count ))
331
+
332
+ print()
333
+ print(" * Writing report file '{}' ... ".format(report_file), end='', flush=True)
334
+ csv_report.write_to_csv(report_file)
335
+ print("DONE")
336
+ print(" * Writing report file '{}' ... ".format(report_file_excel), end='', flush=True)
337
+ csv_report.write_to_excel(report_file_excel)
338
+ print("DONE")
339
+
340
+
341
+ if not request_upgrades:
342
+ print()
343
+ print(" ***** No Agent was switched to Illumination because --confirm option was not used *****")
344
+ print()