-
Notifications
You must be signed in to change notification settings - Fork 390
/
alarmgen_config_handler.py
198 lines (182 loc) · 9.3 KB
/
alarmgen_config_handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#
# Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
#
import socket
from vnc_api.gen.resource_client import Alarm
from vnc_api.gen.resource_xsd import IdPermsType, AlarmExpression, \
AlarmOperand2, AlarmAndList, AlarmOrList, UveKeysType
from pysandesh.gen_py.sandesh.ttypes import SandeshLevel
from config_handler import ConfigHandler
from opserver_util import camel_case_to_hyphen, inverse_dict
from plugins.alarm_base import AlarmBase
from sandesh.viz.constants import UVE_MAP
_INVERSE_UVE_MAP = inverse_dict(UVE_MAP)
class AlarmGenConfigHandler(ConfigHandler):
def __init__(self, module_id, instance_id, logger,
discovery_client, keystone_info, rabbitmq_info,
alarm_plugins, alarm_config_change_callback):
service_id = socket.gethostname()+':'+module_id+':'+instance_id
config_types = ['global-system-config', 'alarm']
super(AlarmGenConfigHandler, self).__init__(service_id, logger,
discovery_client, keystone_info, rabbitmq_info, config_types)
self._alarm_plugins = alarm_plugins
self._alarm_config_change_callback = alarm_config_change_callback
self._inbuilt_alarms = {}
self._config_ownership = False
self._inbuilt_alarms_created = False
self._config_db = {}
self._alarm_config_db = {}
self._create_inbuilt_alarms_config()
# end __init__
def config_db(self):
return self._config_db
# end config_db
def alarm_config_db(self):
return self._alarm_config_db
# end alarm_config_db
def _update_alarm_config_table(self, alarm_fqname, alarm_obj, uve_keys,
operation):
alarm_config_change_map = {}
for key in uve_keys:
try:
table = UVE_MAP[key]
except KeyError:
self._logger('Invalid table name "%s" specified in '
'alarm config "%s"' % (key, alarm_fqname),
SandeshLevel.SYS_ERR)
else:
try:
alarm_table = self._alarm_config_db[table]
except KeyError:
self._alarm_config_db[table] = {}
alarm_table = self._alarm_config_db[table]
finally:
if operation == 'CREATE' or operation == 'UPDATE':
if not isinstance(alarm_obj, AlarmBase):
if alarm_table.has_key(alarm_fqname):
alarm_table[alarm_fqname].set_config(alarm_obj)
else:
alarm_base_obj = AlarmBase(config=alarm_obj)
alarm_table[alarm_fqname] = alarm_base_obj
else:
alarm_table[alarm_fqname] = alarm_obj
elif operation == 'DELETE':
if alarm_table.has_key(alarm_fqname):
del alarm_table[alarm_fqname]
if not len(alarm_table):
del self._alarm_config_db[table]
else:
assert(0)
alarm_config_change_map[table] = {alarm_fqname:operation}
return alarm_config_change_map
# end _update_alarm_config_table
def _create_inbuilt_alarms_config(self):
self._inbuilt_alarms = {}
for table, plugins in self._alarm_plugins.iteritems():
for extn in plugins[table]:
alarm_name = camel_case_to_hyphen(
extn.obj.__class__.__name__)
if self._inbuilt_alarms.has_key(alarm_name):
uve_keys = self._inbuilt_alarms[alarm_name].get_uve_keys()
uve_keys.uve_key.append(_INVERSE_UVE_MAP[table])
self._inbuilt_alarms[alarm_name].set_uve_keys(uve_keys)
else:
alarm_or_list = None
if extn.obj.rules():
alarm_or_list = []
for and_list in extn.obj.rules()['or_list']:
alarm_and_list = []
for exp in and_list['and_list']:
alarm_and_list.append(AlarmExpression(
operation=exp['operation'],
operand1=exp['operand1'],
operand2=AlarmOperand2(uve_attribute=
exp['operand2'].get('uve_attribute'),
json_value=exp['operand2'].get(
'json_value')),
variables=exp.get('variables')))
alarm_or_list.append(AlarmAndList(alarm_and_list))
desc = ' '.join([l.strip() \
for l in extn.obj.__doc__.splitlines()])
id_perms = IdPermsType(creator='system', description=desc)
kwargs = {'parent_type': 'global-system-config',
'fq_name': ['default-global-system-config',
alarm_name]}
self._inbuilt_alarms[alarm_name] = Alarm(name=alarm_name,
uve_keys=UveKeysType([_INVERSE_UVE_MAP[table]]),
alarm_severity=extn.obj.severity(),
alarm_rules=AlarmOrList(alarm_or_list),
id_perms=id_perms, **kwargs)
extn.obj._config = self._inbuilt_alarms[alarm_name]
fqname_str = self._fqname_to_str(extn.obj._config.fq_name)
uve_keys = [_INVERSE_UVE_MAP[table]]
self._update_alarm_config_table(fqname_str, extn.obj,
uve_keys, 'CREATE')
# end _create_inbuilt_alarms_config
def _handle_config_update(self, config_type, fq_name, config_obj,
operation):
self._logger('Handle config %s for %s:%s' % (operation, config_type,
fq_name), SandeshLevel.SYS_INFO)
if not self._config_db.get(config_type):
self._config_db[config_type] = {}
alarm_config_change_map = {}
if operation == 'CREATE' or operation == 'UPDATE':
if config_type == 'alarm':
if '_alarm_rules' not in config_obj.__dict__:
self._logger('Ignoring conf for inbuilt alarm %s' % \
fq_name, SandeshLevel.SYS_INFO)
return
alarm_config = self._config_db[config_type].get(fq_name)
if alarm_config is None:
alarm_config_change_map = self._update_alarm_config_table(
fq_name, config_obj, config_obj.uve_keys.uve_key,
'CREATE')
else:
# If the alarm config already exists, then check for
# addition/deletion of elements from uve_keys and
# update the alarm_config_db appropriately.
add_uve_keys = set(config_obj.uve_keys.uve_key) - \
set(alarm_config.uve_keys.uve_key)
if add_uve_keys:
alarm_config_change_map.update(
self._update_alarm_config_table(
fq_name, config_obj, add_uve_keys, 'CREATE'))
del_uve_keys = set(alarm_config.uve_keys.uve_key) - \
set(config_obj.uve_keys.uve_key)
if del_uve_keys:
alarm_config_change_map.update(
self._update_alarm_config_table(
fq_name, None, del_uve_keys, 'DELETE'))
upd_uve_keys = \
set(config_obj.uve_keys.uve_key).intersection(
set(alarm_config.uve_keys.uve_key))
if upd_uve_keys:
alarm_config_change_map.update(
self._update_alarm_config_table(
fq_name, config_obj, upd_uve_keys, 'UPDATE'))
self._config_db[config_type][fq_name] = config_obj
elif operation == 'DELETE':
config_obj = self._config_db[config_type].get(fq_name)
if config_obj is not None:
if config_type == 'alarm':
alarm_config_change_map = self._update_alarm_config_table(
fq_name, None, config_obj.uve_keys.uve_key, 'DELETE')
del self._config_db[config_type][fq_name]
if not len(self._config_db[config_type]):
del self._config_db[config_type]
else:
# Invalid operation
assert(0)
if alarm_config_change_map:
self._alarm_config_change_callback(alarm_config_change_map)
# end _handle_config_update
def _handle_config_sync(self, config):
for cfg_type, cfg_obj_list in config.iteritems():
self._logger('sync for config type "%s"' % (cfg_type),
SandeshLevel.SYS_INFO)
for cfg_obj in cfg_obj_list:
fq_name = self._fqname_to_str(cfg_obj.fq_name)
self._handle_config_update(cfg_type, fq_name, cfg_obj,
'UPDATE')
# end _handle_config_sync
# end class AlarmGenConfigHandler