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/Workload.py
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
from typing import Optional, List, Union
|
|
2
|
+
|
|
3
|
+
import illumio_pylo as pylo
|
|
4
|
+
from illumio_pylo.API.JsonPayloadTypes import WorkloadObjectJsonStructure
|
|
5
|
+
from illumio_pylo import log
|
|
6
|
+
from .AgentStore import VENAgent
|
|
7
|
+
from .Helpers import *
|
|
8
|
+
from .Exception import PyloEx
|
|
9
|
+
from .Label import Label
|
|
10
|
+
from .ReferenceTracker import ReferenceTracker, Referencer
|
|
11
|
+
from .IPMap import IP4Map
|
|
12
|
+
from .LabeledObject import LabeledObject
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WorkloadInterface:
|
|
16
|
+
def __init__(self, owner: 'pylo.Workload', name: str, ip: Optional[str], network: str, gateway: str, ignored: bool):
|
|
17
|
+
self.owner: Workload = owner
|
|
18
|
+
self.name: str = name
|
|
19
|
+
self.network: str = network
|
|
20
|
+
self.gateway: str = gateway
|
|
21
|
+
self.is_ignored: bool = ignored
|
|
22
|
+
self.ip: Optional[str] = ip
|
|
23
|
+
if ip is not None and len(ip) == 0:
|
|
24
|
+
self.ip = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class WorkloadApiUpdateStack:
|
|
28
|
+
def __init__(self):
|
|
29
|
+
self.json_payload = {}
|
|
30
|
+
|
|
31
|
+
def add_payload(self, data: Dict[str, Any]):
|
|
32
|
+
for prop_name, prop_value in data.items():
|
|
33
|
+
self.json_payload[prop_name] = prop_value
|
|
34
|
+
|
|
35
|
+
def get_payload_and_reset(self) -> Dict[str, Any]:
|
|
36
|
+
data = self.json_payload
|
|
37
|
+
self.json_payload = {}
|
|
38
|
+
return data
|
|
39
|
+
|
|
40
|
+
def count_payloads(self) -> int:
|
|
41
|
+
return len(self.json_payload)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Workload(pylo.ReferenceTracker, pylo.Referencer, LabeledObject):
|
|
45
|
+
|
|
46
|
+
def __init__(self, name: str, href: str, owner: 'pylo.WorkloadStore'):
|
|
47
|
+
ReferenceTracker.__init__(self)
|
|
48
|
+
Referencer.__init__(self)
|
|
49
|
+
LabeledObject.__init__(self)
|
|
50
|
+
self.owner = owner
|
|
51
|
+
self.name: str = name
|
|
52
|
+
self.href: str = href
|
|
53
|
+
self.forced_name: Optional[str] = None
|
|
54
|
+
self.hostname: Optional[str] = None
|
|
55
|
+
|
|
56
|
+
self.description: Optional[str] = None
|
|
57
|
+
self.interfaces: List[WorkloadInterface] = []
|
|
58
|
+
|
|
59
|
+
self.online = False
|
|
60
|
+
|
|
61
|
+
self.os_id: Optional[str] = None
|
|
62
|
+
self.os_detail: Optional[str] = None
|
|
63
|
+
|
|
64
|
+
self.ven_agent: Optional[VENAgent] = None
|
|
65
|
+
|
|
66
|
+
self.unmanaged = True
|
|
67
|
+
|
|
68
|
+
self.temporary = False
|
|
69
|
+
self.deleted = False
|
|
70
|
+
|
|
71
|
+
self.raw_json: Optional[WorkloadObjectJsonStructure] = None
|
|
72
|
+
|
|
73
|
+
self._batch_update_stack: Optional[WorkloadApiUpdateStack] = None
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def loc_label(self) -> Optional['pylo.Label']:
|
|
77
|
+
""" @deprecated use get_label() instead """
|
|
78
|
+
return self.get_label('loc')
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def env_label(self) -> Optional['pylo.Label']:
|
|
82
|
+
""" @deprecated use get_label() instead """
|
|
83
|
+
return self.get_label('env')
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def app_label(self) -> Optional['pylo.Label']:
|
|
87
|
+
""" @deprecated use get_label() instead """
|
|
88
|
+
return self.get_label('app')
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def role_label(self) -> Optional['pylo.Label']:
|
|
92
|
+
""" @deprecated use get_label() instead """
|
|
93
|
+
return self.get_label('role')
|
|
94
|
+
|
|
95
|
+
def load_from_json(self, data):
|
|
96
|
+
"""
|
|
97
|
+
Parse and build workload properties from a PCE API JSON payload. Should be used internally by this library only.
|
|
98
|
+
"""
|
|
99
|
+
label_store = self.owner.owner.LabelStore # forced_name quick access
|
|
100
|
+
|
|
101
|
+
self.raw_json = data
|
|
102
|
+
|
|
103
|
+
self.forced_name = data['name']
|
|
104
|
+
|
|
105
|
+
self.hostname = data['hostname']
|
|
106
|
+
|
|
107
|
+
self.deleted = data['deleted']
|
|
108
|
+
|
|
109
|
+
agent_json = data.get('agent')
|
|
110
|
+
|
|
111
|
+
if agent_json is None:
|
|
112
|
+
raise PyloEx("Workload named '%s' has no Agent record:\n%s" % (
|
|
113
|
+
self.name, nice_json(data)))
|
|
114
|
+
|
|
115
|
+
agent_href = agent_json.get('href')
|
|
116
|
+
if agent_href is None:
|
|
117
|
+
self.unmanaged = True
|
|
118
|
+
else:
|
|
119
|
+
self.unmanaged = False
|
|
120
|
+
self.ven_agent = self.owner.owner.AgentStore.create_ven_agent_from_workload_record(self, agent_json)
|
|
121
|
+
self.online = data['online']
|
|
122
|
+
self.os_id = data.get('os_id')
|
|
123
|
+
#if self.os_id is None:
|
|
124
|
+
# raise PyloEx("Workload named '{}' has no os_id record:\n%s".format(self.name), data)
|
|
125
|
+
self.os_detail = data.get('os_detail')
|
|
126
|
+
#if self.os_detail is None:
|
|
127
|
+
# raise PyloEx("Workload named '{}' has no os_detail record:\n%s".format(self.name), data)
|
|
128
|
+
|
|
129
|
+
self.description = data.get('description')
|
|
130
|
+
|
|
131
|
+
ignored_interfaces_index = {}
|
|
132
|
+
ignored_interfaces_json = data.get('ignored_interface_names')
|
|
133
|
+
|
|
134
|
+
if ignored_interfaces_json is not None:
|
|
135
|
+
for interface_name in ignored_interfaces_json:
|
|
136
|
+
ignored_interfaces_index[interface_name] = True
|
|
137
|
+
|
|
138
|
+
interfaces_json = data.get('interfaces')
|
|
139
|
+
if interfaces_json is not None:
|
|
140
|
+
for interface_json in interfaces_json:
|
|
141
|
+
if_object = WorkloadInterface(self, interface_json.get('name'), interface_json.get('address'),
|
|
142
|
+
interface_json.get('cidr_block'), interface_json.get('default_gateway_address'),
|
|
143
|
+
ignored=interface_json.get('name') in ignored_interfaces_index)
|
|
144
|
+
self.interfaces.append(if_object)
|
|
145
|
+
|
|
146
|
+
if 'labels' in data:
|
|
147
|
+
labels = data['labels']
|
|
148
|
+
for label in labels:
|
|
149
|
+
if 'href' not in label:
|
|
150
|
+
raise PyloEx("Workload named '%s' has labels in JSON but without any HREF:\n%s" % (
|
|
151
|
+
self.get_name(), nice_json(labels)))
|
|
152
|
+
href = label['href']
|
|
153
|
+
label_object = label_store.find_by_href(href)
|
|
154
|
+
if label_object is None:
|
|
155
|
+
if not self.deleted:
|
|
156
|
+
raise pylo.PyloObjectNotFound(
|
|
157
|
+
"Workload '%s'/'%s' is referencing label href '%s' which does not exist" % (
|
|
158
|
+
self.name, self.href, href))
|
|
159
|
+
|
|
160
|
+
self.set_label(label_object)
|
|
161
|
+
# print("Workload '%s'/'%s' is referencing label '%s'/'%s'" % (self.name, self.hostname, label_object.type, label_object.name))
|
|
162
|
+
|
|
163
|
+
label_object.add_reference(self)
|
|
164
|
+
|
|
165
|
+
def interfaces_to_string(self, separator: str = ',', show_ignored: bool = True, show_interface_name: bool = True) -> str:
|
|
166
|
+
"""
|
|
167
|
+
Conveniently outputs all interface of this Workload to a string.
|
|
168
|
+
|
|
169
|
+
:param separator: string used to separate each interface in the string
|
|
170
|
+
:param show_ignored: whether or not ignored interfaces should be showing
|
|
171
|
+
:param show_interface_name:
|
|
172
|
+
:return: string with interfaces split by specified separator
|
|
173
|
+
"""
|
|
174
|
+
tmp = []
|
|
175
|
+
|
|
176
|
+
for interface in self.interfaces:
|
|
177
|
+
if not show_ignored and interface.is_ignored:
|
|
178
|
+
continue
|
|
179
|
+
if show_interface_name:
|
|
180
|
+
tmp.append('{}:{}'.format(interface.name, interface.ip if interface.ip is not None else 'UnknownIP'))
|
|
181
|
+
else:
|
|
182
|
+
tmp.append(interface.ip if interface.ip is not None else 'UnknownIP')
|
|
183
|
+
|
|
184
|
+
return pylo.string_list_to_text(tmp, separator)
|
|
185
|
+
|
|
186
|
+
def get_ip4map_from_interfaces(self) -> pylo.IP4Map:
|
|
187
|
+
"""
|
|
188
|
+
Calculate and return a map of all IP4 covered by the Workload interfaces
|
|
189
|
+
"""
|
|
190
|
+
result = IP4Map()
|
|
191
|
+
|
|
192
|
+
for interface in self.interfaces:
|
|
193
|
+
if interface.ip is not None:
|
|
194
|
+
result.add_from_text(interface.ip)
|
|
195
|
+
|
|
196
|
+
return result
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def created_at(self) -> str:
|
|
200
|
+
return self.raw_json['created_at']
|
|
201
|
+
|
|
202
|
+
def is_using_label(self, label: Union['pylo.Label', 'pylo.LabelGroup']) -> bool:
|
|
203
|
+
"""
|
|
204
|
+
Check if a label is used by this Workload
|
|
205
|
+
:param label: label to check for usage. If it's a label group then it will check that at least one label of the group is used
|
|
206
|
+
:return: true if label is used by this workload
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
# check for label class
|
|
210
|
+
if isinstance(label, pylo.Label):
|
|
211
|
+
if self.loc_label is label or self.env_label is label \
|
|
212
|
+
or self.app_label is label or self.app_label is label:
|
|
213
|
+
return True
|
|
214
|
+
else:
|
|
215
|
+
for member_label in label.get_members().values():
|
|
216
|
+
if self.is_using_label(member_label):
|
|
217
|
+
return True
|
|
218
|
+
return False
|
|
219
|
+
|
|
220
|
+
def api_update_description(self, new_description: str):
|
|
221
|
+
data = {'description': new_description}
|
|
222
|
+
if self._batch_update_stack is None:
|
|
223
|
+
connector = pylo.find_connector_or_die(self.owner)
|
|
224
|
+
connector.objects_workload_update(self.href, data=data)
|
|
225
|
+
else:
|
|
226
|
+
self._batch_update_stack.add_payload(data)
|
|
227
|
+
self.description = new_description
|
|
228
|
+
|
|
229
|
+
def api_update_hostname(self, new_hostname: str):
|
|
230
|
+
data = {'hostname': new_hostname}
|
|
231
|
+
if self._batch_update_stack is None:
|
|
232
|
+
connector = pylo.find_connector_or_die(self.owner)
|
|
233
|
+
connector.objects_workload_update(self.href, data=data)
|
|
234
|
+
else:
|
|
235
|
+
self._batch_update_stack.add_payload(data)
|
|
236
|
+
|
|
237
|
+
self.raw_json.update(data)
|
|
238
|
+
self.hostname = new_hostname
|
|
239
|
+
|
|
240
|
+
def api_update_forced_name(self, name: str):
|
|
241
|
+
|
|
242
|
+
data = {'name': name}
|
|
243
|
+
if self._batch_update_stack is None:
|
|
244
|
+
connector = pylo.find_connector_or_die(self.owner)
|
|
245
|
+
connector.objects_workload_update(self.href, data=data)
|
|
246
|
+
else:
|
|
247
|
+
self._batch_update_stack.add_payload(data)
|
|
248
|
+
|
|
249
|
+
self.raw_json.update(data)
|
|
250
|
+
self.forced_name = name
|
|
251
|
+
|
|
252
|
+
def api_update_labels(self, list_of_labels: Optional[List[Label]] = None, missing_label_type_means_no_change=False):
|
|
253
|
+
"""
|
|
254
|
+
Push Workload's assigned Labels to the PCE.
|
|
255
|
+
|
|
256
|
+
:param list_of_labels: labels to replace currently assigned ones. If not specified it will push current labels instead.
|
|
257
|
+
:param missing_label_type_means_no_change: if a label type is missing and this is False then existing label of type in the Workload will be removed
|
|
258
|
+
:return:
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
if list_of_labels is not None:
|
|
262
|
+
# a list of labels were specified so are first going to change
|
|
263
|
+
if not self.update_labels(list_of_labels, missing_label_type_means_no_change):
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
label_data = []
|
|
267
|
+
if self.loc_label is not None:
|
|
268
|
+
label_data.append({'href': self.loc_label.href})
|
|
269
|
+
if self.env_label is not None:
|
|
270
|
+
label_data.append({'href': self.env_label.href})
|
|
271
|
+
if self.app_label is not None:
|
|
272
|
+
label_data.append({'href': self.app_label.href})
|
|
273
|
+
if self.role_label is not None:
|
|
274
|
+
label_data.append({'href': self.role_label.href})
|
|
275
|
+
|
|
276
|
+
data = {'labels': label_data}
|
|
277
|
+
|
|
278
|
+
if self._batch_update_stack is None:
|
|
279
|
+
connector = pylo.find_connector_or_die(self.owner)
|
|
280
|
+
connector.objects_workload_update(self.href, data)
|
|
281
|
+
else:
|
|
282
|
+
self._batch_update_stack.add_payload(data)
|
|
283
|
+
|
|
284
|
+
self.raw_json.update(data)
|
|
285
|
+
|
|
286
|
+
def api_stacked_updates_start(self):
|
|
287
|
+
"""
|
|
288
|
+
Turns on 'updates stacking' mode for this Worklaod which will not push changes to API as you make them but only
|
|
289
|
+
when you trigger 'api_push_stacked_updates()' function
|
|
290
|
+
"""
|
|
291
|
+
self._batch_update_stack = WorkloadApiUpdateStack()
|
|
292
|
+
|
|
293
|
+
def api_stacked_updates_push(self):
|
|
294
|
+
"""
|
|
295
|
+
Push all stacked changed to API and turns off 'updates stacking' mode
|
|
296
|
+
"""
|
|
297
|
+
if self._batch_update_stack is None:
|
|
298
|
+
raise PyloEx("Workload was not in 'update stacking' mode")
|
|
299
|
+
|
|
300
|
+
connector = pylo.find_connector_or_die(self.owner)
|
|
301
|
+
connector.objects_workload_update(self.href, self._batch_update_stack.get_payload_and_reset())
|
|
302
|
+
self._batch_update_stack = None
|
|
303
|
+
|
|
304
|
+
def api_stacked_updates_count(self) -> int:
|
|
305
|
+
"""
|
|
306
|
+
Counts the number of stacked changed for this Workload
|
|
307
|
+
:return:
|
|
308
|
+
"""
|
|
309
|
+
if self._batch_update_stack is None:
|
|
310
|
+
raise PyloEx("Workload was not in 'update stacking' mode")
|
|
311
|
+
return self._batch_update_stack.count_payloads()
|
|
312
|
+
|
|
313
|
+
def get_labels_str(self, separator: str = '|') -> str:
|
|
314
|
+
"""
|
|
315
|
+
Conveniently returns a string with all labels names in RAEL order
|
|
316
|
+
:param separator: default separator is |
|
|
317
|
+
:return: example: *None*|AppA|EnvC|LocZ
|
|
318
|
+
"""
|
|
319
|
+
labels = ''
|
|
320
|
+
|
|
321
|
+
first = True
|
|
322
|
+
for dimensions in self.owner.owner.LabelStore.label_types:
|
|
323
|
+
label = self.get_label(dimensions)
|
|
324
|
+
if not first:
|
|
325
|
+
labels += separator
|
|
326
|
+
if label is not None:
|
|
327
|
+
labels += label.name
|
|
328
|
+
else:
|
|
329
|
+
labels += '*None*'
|
|
330
|
+
first = False
|
|
331
|
+
|
|
332
|
+
return labels
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def get_appgroup_str(self, separator: str = '|') -> str:
|
|
336
|
+
labels = ''
|
|
337
|
+
|
|
338
|
+
if self.app_label is None:
|
|
339
|
+
labels += '*None*' + separator
|
|
340
|
+
else:
|
|
341
|
+
labels += self.app_label.name + separator
|
|
342
|
+
|
|
343
|
+
if self.env_label is None:
|
|
344
|
+
labels += '*None*' + separator
|
|
345
|
+
else:
|
|
346
|
+
labels += self.env_label.name + separator
|
|
347
|
+
|
|
348
|
+
if self.loc_label is None:
|
|
349
|
+
labels += '*None*'
|
|
350
|
+
else:
|
|
351
|
+
labels += self.loc_label.name
|
|
352
|
+
|
|
353
|
+
return labels
|
|
354
|
+
|
|
355
|
+
def get_labels_str_list(self, missing_str: Optional[str] = '') -> List[str]:
|
|
356
|
+
"""
|
|
357
|
+
Conveniently returns the list of Workload labels as a list of strings
|
|
358
|
+
:param missing_str: if a label type is missing then missing_str will be used to represent it
|
|
359
|
+
:return:
|
|
360
|
+
"""
|
|
361
|
+
labels = []
|
|
362
|
+
|
|
363
|
+
if self.role_label is None:
|
|
364
|
+
labels.append(missing_str)
|
|
365
|
+
else:
|
|
366
|
+
labels.append(self.role_label.name)
|
|
367
|
+
|
|
368
|
+
if self.app_label is None:
|
|
369
|
+
labels.append(missing_str)
|
|
370
|
+
else:
|
|
371
|
+
labels.append(self.app_label.name)
|
|
372
|
+
|
|
373
|
+
if self.env_label is None:
|
|
374
|
+
labels.append(missing_str)
|
|
375
|
+
else:
|
|
376
|
+
labels.append(self.env_label.name)
|
|
377
|
+
|
|
378
|
+
if self.loc_label is None:
|
|
379
|
+
labels.append(missing_str)
|
|
380
|
+
else:
|
|
381
|
+
labels.append(self.loc_label.name)
|
|
382
|
+
|
|
383
|
+
return labels
|
|
384
|
+
|
|
385
|
+
def get_name(self) -> str:
|
|
386
|
+
"""
|
|
387
|
+
Return forced name if it exists, hostname otherwise
|
|
388
|
+
|
|
389
|
+
:return:
|
|
390
|
+
"""
|
|
391
|
+
if self.forced_name is not None:
|
|
392
|
+
return self.forced_name
|
|
393
|
+
if self.hostname is None:
|
|
394
|
+
pylo.get_logger().warning("workload with href '{}' has no name nor host name".format(self.href))
|
|
395
|
+
return "*unknown*"
|
|
396
|
+
return self.hostname
|
|
397
|
+
|
|
398
|
+
def get_name_stripped_fqdn(self):
|
|
399
|
+
name_split = self.get_name().split('.')
|
|
400
|
+
return name_split[0]
|
|
401
|
+
|
|
402
|
+
@staticmethod
|
|
403
|
+
def static_name_stripped_fqdn(name: str):
|
|
404
|
+
name_split = name.split('.')
|
|
405
|
+
return name_split[0]
|
|
406
|
+
|
|
407
|
+
def get_status_string(self) -> str:
|
|
408
|
+
if self.ven_agent is None:
|
|
409
|
+
return 'not-applicable'
|
|
410
|
+
return self.ven_agent.mode
|
|
411
|
+
|
|
412
|
+
def update_labels(self, list_of_labels: List[Label], missing_label_type_means_no_change=False) -> bool:
|
|
413
|
+
"""
|
|
414
|
+
WARNING: this will not send updates to PCE API, use the 'api_' prefixed function for that
|
|
415
|
+
|
|
416
|
+
:param list_of_labels: labels to replace currently assigned ones
|
|
417
|
+
:param missing_label_type_means_no_change: if a label type is missing and this is False then existing label of type in the Workload will be removed
|
|
418
|
+
:return:
|
|
419
|
+
"""
|
|
420
|
+
changes_occurred = False
|
|
421
|
+
role_label: Optional[Label] = None
|
|
422
|
+
app_label: Optional[Label] = None
|
|
423
|
+
env_label: Optional[Label] = None
|
|
424
|
+
loc_label: Optional[Label] = None
|
|
425
|
+
|
|
426
|
+
if len(list_of_labels) > 4:
|
|
427
|
+
raise PyloEx("More than 4 labels provided")
|
|
428
|
+
|
|
429
|
+
for label in list_of_labels:
|
|
430
|
+
if label.type_is_role():
|
|
431
|
+
if role_label is not None:
|
|
432
|
+
raise PyloEx("ROLE label specified more than once ('{}' vs '{}')".format(role_label.name, label.name))
|
|
433
|
+
role_label = label
|
|
434
|
+
elif label.type_is_application():
|
|
435
|
+
if app_label is not None:
|
|
436
|
+
raise PyloEx("APP label specified more than once ('{}' vs '{}')".format(app_label.name, label.name))
|
|
437
|
+
app_label = label
|
|
438
|
+
elif label.type_is_environment():
|
|
439
|
+
if env_label is not None:
|
|
440
|
+
raise PyloEx("ENV label specified more than once ('{}' vs '{}')".format(env_label.name, label.name))
|
|
441
|
+
env_label = label
|
|
442
|
+
elif label.type_is_location():
|
|
443
|
+
if loc_label is not None:
|
|
444
|
+
raise PyloEx("LOC label specified more than once ('{}' vs '{}')".format(loc_label.name, label.name))
|
|
445
|
+
loc_label = label
|
|
446
|
+
|
|
447
|
+
if role_label is None:
|
|
448
|
+
if not missing_label_type_means_no_change:
|
|
449
|
+
if self.role_label is not None:
|
|
450
|
+
changes_occurred = True
|
|
451
|
+
self.role_label.remove_reference(self)
|
|
452
|
+
self.role_label = None
|
|
453
|
+
elif role_label is not self.role_label:
|
|
454
|
+
changes_occurred = True
|
|
455
|
+
if self.role_label is not None:
|
|
456
|
+
self.role_label.remove_reference(self)
|
|
457
|
+
role_label.add_reference(self)
|
|
458
|
+
self.role_label = role_label
|
|
459
|
+
|
|
460
|
+
if app_label is None:
|
|
461
|
+
if not missing_label_type_means_no_change:
|
|
462
|
+
if self.app_label is not None:
|
|
463
|
+
changes_occurred = True
|
|
464
|
+
self.app_label.remove_reference(self)
|
|
465
|
+
self.app_label = None
|
|
466
|
+
elif app_label is not self.app_label:
|
|
467
|
+
changes_occurred = True
|
|
468
|
+
if self.app_label is not None:
|
|
469
|
+
self.app_label.remove_reference(self)
|
|
470
|
+
app_label.add_reference(self)
|
|
471
|
+
self.app_label = app_label
|
|
472
|
+
|
|
473
|
+
if env_label is None:
|
|
474
|
+
if not missing_label_type_means_no_change:
|
|
475
|
+
if self.env_label is not None:
|
|
476
|
+
changes_occurred = True
|
|
477
|
+
self.env_label.remove_reference(self)
|
|
478
|
+
self.env_label = None
|
|
479
|
+
elif env_label is not self.env_label:
|
|
480
|
+
changes_occurred = True
|
|
481
|
+
if self.env_label is not None:
|
|
482
|
+
self.env_label.remove_reference(self)
|
|
483
|
+
env_label.add_reference(self)
|
|
484
|
+
self.env_label = env_label
|
|
485
|
+
|
|
486
|
+
if loc_label is None:
|
|
487
|
+
if not missing_label_type_means_no_change:
|
|
488
|
+
if self.loc_label is not None:
|
|
489
|
+
changes_occurred = True
|
|
490
|
+
self.loc_label.remove_reference(self)
|
|
491
|
+
self.loc_label = None
|
|
492
|
+
elif loc_label is not self.loc_label:
|
|
493
|
+
changes_occurred = True
|
|
494
|
+
if self.loc_label is not None:
|
|
495
|
+
self.loc_label.remove_reference(self)
|
|
496
|
+
loc_label.add_reference(self)
|
|
497
|
+
self.loc_label = loc_label
|
|
498
|
+
|
|
499
|
+
return changes_occurred
|
|
500
|
+
|
|
501
|
+
def get_pce_ui_url(self) -> str:
|
|
502
|
+
"""
|
|
503
|
+
generates a URL link for the Workload vs PCE UI
|
|
504
|
+
:return: url string
|
|
505
|
+
"""
|
|
506
|
+
return self.owner.owner.connector.get_pce_ui_workload_url(self.href)
|