1
|
|
|
"""Module with common classes for the controller.""" |
2
|
|
|
from enum import Enum |
3
|
|
|
|
4
|
|
|
from kytos.core.config import KytosConfig |
5
|
|
|
|
6
|
|
|
__all__ = ('GenericEntity',) |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
class EntityStatus(Enum): |
10
|
|
|
"""Enumeration of possible statuses for GenericEntity instances.""" |
11
|
|
|
|
12
|
|
|
UP = "UP" |
13
|
|
|
DISABLED = "DISABLED" |
14
|
|
|
DOWN = "DOWN" |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
class GenericEntity: |
18
|
|
|
"""Generic class that represents any Entity.""" |
19
|
|
|
|
20
|
|
|
def __init__(self): |
21
|
|
|
"""Create the GenericEntity object with empty metadata dictionary.""" |
22
|
|
|
options = KytosConfig().options['daemon'] |
23
|
|
|
self.metadata = {} |
24
|
|
|
|
25
|
|
|
self._active: bool = True |
26
|
|
|
self._enabled: bool = options.enable_entities_by_default |
27
|
|
|
|
28
|
|
|
def is_enabled(self) -> bool: |
29
|
|
|
"""Return the *administrative* status of the entity.""" |
30
|
|
|
return self._enabled |
31
|
|
|
|
32
|
|
|
def is_active(self) -> bool: |
33
|
|
|
"""Return the *operational* status of the entity.""" |
34
|
|
|
return self._active |
35
|
|
|
|
36
|
|
|
def activate(self): |
37
|
|
|
"""Activate the entity.""" |
38
|
|
|
self._active = True |
39
|
|
|
|
40
|
|
|
def deactivate(self): |
41
|
|
|
"""Deactivate the entity.""" |
42
|
|
|
self._active = False |
43
|
|
|
|
44
|
|
|
@property |
45
|
|
|
def status(self): |
46
|
|
|
"""Return the current status of the Entity.""" |
47
|
|
|
if self.is_enabled() and self.is_active(): |
48
|
|
|
return EntityStatus.UP |
49
|
|
|
if self.is_administrative_down(): |
50
|
|
|
return EntityStatus.DISABLED |
51
|
|
|
return EntityStatus.DOWN |
52
|
|
|
|
53
|
|
|
@property |
54
|
|
|
def status_reason(self): |
55
|
|
|
"""Return the reason behind the current status of the entity.""" |
56
|
|
|
reasons = set() |
57
|
|
|
if not self.is_enabled(): |
58
|
|
|
reasons.add('disabled') |
59
|
|
|
if not self.is_active(): |
60
|
|
|
reasons.add('deactivated') |
61
|
|
|
return reasons |
62
|
|
|
|
63
|
|
|
def is_administrative_down(self): |
64
|
|
|
"""Return True for disabled Entities.""" |
65
|
|
|
return not self.is_enabled() |
66
|
|
|
|
67
|
|
|
def enable(self): |
68
|
|
|
"""Administratively enable the Entity. |
69
|
|
|
|
70
|
|
|
Although this method only sets an 'enabled' flag, always prefer to use |
71
|
|
|
it instead of setting it manually. This allows us to change the |
72
|
|
|
behavior in the future. |
73
|
|
|
""" |
74
|
|
|
self._enabled = True |
75
|
|
|
|
76
|
|
|
def disable(self): |
77
|
|
|
"""Administratively disable the Entity. |
78
|
|
|
|
79
|
|
|
This method can disable other related entities. For this behavior, |
80
|
|
|
rewrite it on the child classes. |
81
|
|
|
""" |
82
|
|
|
self._enabled = False |
83
|
|
|
|
84
|
|
|
def add_metadata(self, key, value): |
85
|
|
|
"""Add a new metadata (key, value).""" |
86
|
|
|
if key in self.metadata: |
87
|
|
|
return False |
88
|
|
|
|
89
|
|
|
self.metadata[key] = value |
90
|
|
|
return True |
91
|
|
|
|
92
|
|
|
def remove_metadata(self, key): |
93
|
|
|
"""Try to remove a specific metadata.""" |
94
|
|
|
try: |
95
|
|
|
del self.metadata[key] |
96
|
|
|
return True |
97
|
|
|
except KeyError: |
98
|
|
|
return False |
99
|
|
|
|
100
|
|
|
def get_metadata(self, key): |
101
|
|
|
"""Try to get a specific metadata.""" |
102
|
|
|
return self.metadata.get(key) |
103
|
|
|
|
104
|
|
|
def get_metadata_as_dict(self): |
105
|
|
|
"""Get all metadata values as dict.""" |
106
|
|
|
metadata = dict(self.metadata) |
107
|
|
|
for key, value in self.metadata.items(): |
108
|
|
|
if hasattr(value, 'as_dict'): |
109
|
|
|
metadata[key] = value.as_dict() |
110
|
|
|
return metadata |
111
|
|
|
|
112
|
|
|
def update_metadata(self, key, value): |
113
|
|
|
"""Overwrite a specific metadata.""" |
114
|
|
|
self.metadata[key] = value |
115
|
|
|
|
116
|
|
|
def clear_metadata(self): |
117
|
|
|
"""Remove all metadata information.""" |
118
|
|
|
self.metadata = {} |
119
|
|
|
|
120
|
|
|
def extend_metadata(self, metadatas, force=True): |
121
|
|
|
"""Extend the metadata information. |
122
|
|
|
|
123
|
|
|
If force is True any existing value is overwritten. |
124
|
|
|
""" |
125
|
|
|
if force: |
126
|
|
|
self.metadata.update(metadatas) |
127
|
|
|
return |
128
|
|
|
|
129
|
|
|
for key, value in metadatas.items(): |
130
|
|
|
self.add_metadata(key, value) |
131
|
|
|
|