Skip to content

Commit

Permalink
Change in schema for operand2 in alarm config
Browse files Browse the repository at this point in the history
- operand2 in AlarmExpression can be either a uve attribute or a json
value. Presently, it is defined as a string. Schema of operand2 has been
changed to make it explicit that operand2 can take either uve
attribute or json value.

Closes-Bug: #1607030

Presently, severity level for alarm is 0-7. Restricted the
severity level to 0-2 (0- critical, 1 - major, 2 - minor)

Change-Id: I3cfe2d987da023976f674a2c8c4c21e216a7d994
Closes-Bug: #1606676
  • Loading branch information
Sundaresan Rajangam committed Aug 3, 2016
1 parent 17e4a50 commit 9677cd5
Show file tree
Hide file tree
Showing 23 changed files with 311 additions and 145 deletions.
33 changes: 31 additions & 2 deletions src/config/api-server/vnc_cfg_types.py
Expand Up @@ -2010,24 +2010,53 @@ def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn, **kwargs):
return (True, '')
# end class ForwardingClassServer


class AlarmServer(Resource, Alarm):

@classmethod
def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
if 'alarm_rules' not in obj_dict or obj_dict['alarm_rules'] is None:
return (False, (400, 'alarm_rules not specified or null'))
(ok, error) = cls._check_alarm_rules(obj_dict['alarm_rules'])
if not ok:
return (False, error)
return True, ''
# end pre_dbe_create

@classmethod
def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn, **kwargs):
if 'alarm_rules' in obj_dict and obj_dict['alarm_rules'] is None:
return (False, (400, 'alarm_rules cannot be removed'))
if 'alarm_rules' in obj_dict:
if obj_dict['alarm_rules'] is None:
return (False, (400, 'alarm_rules cannot be removed'))
(ok, error) = cls._check_alarm_rules(obj_dict['alarm_rules'])
if not ok:
return (False, error)
return True, ''
# end pre_dbe_update

@classmethod
def _check_alarm_rules(cls, alarm_rules):
try:
for and_list in alarm_rules['or_list']:
for and_cond in and_list['and_list']:
if 'json_value' in and_cond['operand2']:
if 'uve_attribute' in and_cond['operand2']:
return (False, (400, 'operand2 should have either '
'"uve_attribute" or "json_value", not both'))
try:
json.loads(and_cond['operand2']['json_value'])
except ValueError:
return (False, (400, 'Invalid json_value %s '
'specified in alarm_rules' %
(and_cond['operand2']['json_value'])))
except Exception as e:
return (False, (400, 'Invalid alarm_rules'))
return (True, '')
# end _check_alarm_rules

# end class AlarmServer


class QosConfigServer(Resource, QosConfig):
@classmethod
def _check_qos_values(cls, obj_dict, db_conn):
Expand Down
24 changes: 14 additions & 10 deletions src/opserver/alarmgen.py
Expand Up @@ -30,8 +30,8 @@
from pysandesh.sandesh_logger import SandeshLogger
from pysandesh.gen_py.sandesh_alarm.ttypes import SandeshAlarmAckResponseCode
from sandesh.alarmgen_ctrl.sandesh_alarm_base.ttypes import AlarmTrace, \
UVEAlarms, UVEAlarmInfo, UVEAlarmConfig, AlarmCondition, AlarmMatch, \
AlarmConditionMatch, AlarmAndList, AlarmRules
UVEAlarms, UVEAlarmInfo, UVEAlarmConfig, AlarmOperand2, AlarmCondition, \
AlarmMatch, AlarmConditionMatch, AlarmAndList, AlarmRules
from sandesh.analytics.ttypes import *
from sandesh.nodeinfo.ttypes import NodeStatusUVE, NodeStatus
from sandesh.nodeinfo.cpuinfo.ttypes import *
Expand Down Expand Up @@ -288,7 +288,8 @@ def _get_json_variables(self, uve, exp, operand1_val,
var_val = \
operand1_val['parent_attr'].get(var.rsplit('.', 1)[1])
elif not is_operand2_json_val and \
var.rsplit('.', 1)[0] == exp.operand2.rsplit('.', 1)[0]:
var.rsplit('.', 1)[0] == exp.operand2.uve_attribute.rsplit(
'.', 1)[0]:
var_val = \
operand2_val['parent_attr'].get(var.rsplit('.', 1)[1])
else:
Expand Down Expand Up @@ -342,7 +343,7 @@ def _get_alarm_match(self, uve, exp, operand1_val, operand2_val,
else:
json_operand2_val = None
return AlarmMatch(json_operand1_value=json_operand1_val,
json_operand2_value=json_operand2_val, json_vars=json_vars)
json_operand2_value=json_operand2_val, json_variables=json_vars)
# end _get_alarm_match

def _get_alarm_condition_match(self, uve, exp, operand1_val, operand2_val,
Expand All @@ -352,8 +353,10 @@ def _get_alarm_condition_match(self, uve, exp, operand1_val, operand2_val,
operand2_val, is_operand2_json_val)]
return AlarmConditionMatch(
condition=AlarmCondition(operation=exp.operation,
operand1=exp.operand1, operand2=exp.operand2,
vars=exp.variables),
operand1=exp.operand1, operand2=AlarmOperand2(
uve_attribute=exp.operand2.uve_attribute,
json_value=exp.operand2.json_value),
variables=exp.variables),
match=match_list)
# end _get_alarm_condition_match

Expand All @@ -375,11 +378,12 @@ def _evaluate_uve_for_alarms(self, alarm_cfg, uve_key, uve):
operand1_val['status'] is False:
and_list_fail = True
break
try:
operand2_val = json.loads(exp.operand2)
if exp.operand2.json_value is not None:
operand2_val = json.loads(exp.operand2.json_value)
is_operand2_json_val = True
except ValueError:
operand2_val = self._get_operand_value(uve, exp.operand2)
else:
operand2_val = self._get_operand_value(uve,
exp.operand2.uve_attribute)
if isinstance(operand2_val, dict) and \
operand2_val['status'] is False:
and_list_fail = True
Expand Down
7 changes: 5 additions & 2 deletions src/opserver/alarmgen_config_handler.py
Expand Up @@ -7,7 +7,7 @@

from vnc_api.gen.resource_client import Alarm
from vnc_api.gen.resource_xsd import IdPermsType, AlarmExpression, \
AlarmAndList, AlarmOrList, UveKeysType
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
Expand Down Expand Up @@ -102,7 +102,10 @@ def _create_inbuilt_alarms_config(self):
alarm_and_list.append(AlarmExpression(
operation=exp['operation'],
operand1=exp['operand1'],
operand2=exp['operand2'],
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() \
Expand Down
17 changes: 12 additions & 5 deletions src/opserver/plugins/alarm_address_mismatch/main.py
Expand Up @@ -14,7 +14,9 @@ class AddressMismatchCompute(AlarmBase):
'operand1': 'ContrailConfig.elements.' + \
'virtual_router_ip_address',
'operation': 'not in',
'operand2': 'VrouterAgent.self_ip_list'
'operand2': {
'uve_attribute': 'VrouterAgent.self_ip_list'
}
}
]
},
Expand All @@ -24,15 +26,17 @@ class AddressMismatchCompute(AlarmBase):
'operand1': 'ContrailConfig.elements.' + \
'virtual_router_ip_address',
'operation': '!=',
'operand2': 'VrouterAgent.control_ip'
'operand2': {
'uve_attribute': 'VrouterAgent.control_ip'
}
}
]
}
]
}

def __init__(self):
AlarmBase.__init__(self, AlarmBase.SYS_ERR)
AlarmBase.__init__(self, AlarmBase.ALARM_MAJOR)


class AddressMismatchControl(AlarmBase):
Expand All @@ -48,12 +52,15 @@ class AddressMismatchControl(AlarmBase):
'operand1': 'ContrailConfig.elements.' + \
'bgp_router_parameters.address',
'operation': 'not in',
'operand2': 'BgpRouterState.bgp_router_ip_list'
'operand2': {
'uve_attribute':
'BgpRouterState.bgp_router_ip_list'
}
}
]
}
]
}

def __init__(self):
AlarmBase.__init__(self, AlarmBase.SYS_ERR)
AlarmBase.__init__(self, AlarmBase.ALARM_MAJOR)
7 changes: 3 additions & 4 deletions src/opserver/plugins/alarm_base.py
Expand Up @@ -5,14 +5,13 @@ class AlarmBase(object):
"""Base class for Alarms
"""

SYS_EMERG, SYS_ALERT, SYS_CRIT, SYS_ERR,\
SYS_WARN, SYS_NOTICE, SYS_INFO, SYS_DEBUG = range(8)
ALARM_CRITICAL, ALARM_MAJOR, ALARM_MINOR = range(3)

_RULES = None

def __init__(self, sev=None, at=0, it=0, fec=False,
fcs=0, fct=0, config=None):
self._sev = sev or self.SYS_ERR
self._sev = sev or self.ALARM_MAJOR
self._ActiveTimer = at
self._IdleTimer = it
self._FreqExceededCheck = fec
Expand Down Expand Up @@ -89,5 +88,5 @@ def is_enabled(self):
alarm processing engine.
:param uve_key: Key of the UVE (a string)
:param uve_data: UVE Contents
:returns: list of AlarmRuleMatch
:returns: list of AlarmAndList
"""
10 changes: 7 additions & 3 deletions src/opserver/plugins/alarm_bgp_connectivity/main.py
Expand Up @@ -12,7 +12,9 @@ class BgpConnectivity(AlarmBase):
{
'operand1': 'BgpRouterState.num_up_bgp_peer',
'operation': '==',
'operand2': 'null'
'operand2': {
'json_value': 'null'
}
}
]
},
Expand All @@ -21,12 +23,14 @@ class BgpConnectivity(AlarmBase):
{
'operand1': 'BgpRouterState.num_up_bgp_peer',
'operation': '!=',
'operand2': 'BgpRouterState.num_bgp_peer'
'operand2': {
'uve_attribute': 'BgpRouterState.num_bgp_peer'
}
}
]
}
]
}

def __init__(self):
AlarmBase.__init__(self, AlarmBase.SYS_WARN)
AlarmBase.__init__(self, AlarmBase.ALARM_MAJOR)
6 changes: 4 additions & 2 deletions src/opserver/plugins/alarm_config_incorrect/main.py
Expand Up @@ -12,12 +12,14 @@ class ConfIncorrect(AlarmBase):
{
'operand1': 'ContrailConfig',
'operation': '==',
'operand2': 'null'
'operand2': {
'json_value': 'null'
}
}
]
}
]
}

def __init__(self, sev = AlarmBase.SYS_ERR):
def __init__(self, sev = AlarmBase.ALARM_MAJOR):
AlarmBase.__init__(self, sev)
6 changes: 4 additions & 2 deletions src/opserver/plugins/alarm_disk_usage/main.py
Expand Up @@ -13,7 +13,9 @@ class DiskUsage(AlarmBase):
'operand1': 'NodeStatus.disk_usage_info.' + \
'percentage_partition_space_used',
'operation': '>=',
'operand2': '90',
'operand2': {
'json_value': '90'
},
'variables': \
['NodeStatus.disk_usage_info.partition_name']
}
Expand All @@ -23,4 +25,4 @@ class DiskUsage(AlarmBase):
}

def __init__(self):
AlarmBase.__init__(self, AlarmBase.SYS_ERR)
AlarmBase.__init__(self, AlarmBase.ALARM_CRITICAL)
6 changes: 4 additions & 2 deletions src/opserver/plugins/alarm_node_status/main.py
Expand Up @@ -12,12 +12,14 @@ class NodeStatus(AlarmBase):
{
'operand1': 'NodeStatus',
'operation': '==',
'operand2': 'null'
'operand2': {
'json_value': 'null'
}
}
]
}
]
}

def __init__(self):
AlarmBase.__init__(self, AlarmBase.SYS_CRIT)
AlarmBase.__init__(self, AlarmBase.ALARM_CRITICAL)
18 changes: 13 additions & 5 deletions src/opserver/plugins/alarm_partial_sysinfo/main.py
Expand Up @@ -4,7 +4,7 @@
class PartialSysinfo(AlarmBase):

def __init__(self):
AlarmBase.__init__(self, AlarmBase.SYS_WARN)
AlarmBase.__init__(self, AlarmBase.ALARM_MAJOR)


class PartialSysinfoCompute(PartialSysinfo):
Expand All @@ -18,7 +18,9 @@ class PartialSysinfoCompute(PartialSysinfo):
{
'operand1': 'VrouterAgent.build_info',
'operation': '==',
'operand2': 'null'
'operand2': {
'json_value': 'null'
}
}
]
}
Expand All @@ -37,7 +39,9 @@ class PartialSysinfoAnalytics(PartialSysinfo):
{
'operand1': 'CollectorState.build_info',
'operation': '==',
'operand2': 'null'
'operand2': {
'json_value': 'null'
}
}
]
}
Expand All @@ -56,7 +60,9 @@ class PartialSysinfoConfig(PartialSysinfo):
{
'operand1': 'ModuleCpuState.build_info',
'operation': '==',
'operand2': 'null'
'operand2': {
'json_value': 'null'
}
}
]
}
Expand All @@ -75,7 +81,9 @@ class PartialSysinfoControl(PartialSysinfo):
{
'operand1': 'BgpRouterState.build_info',
'operation': '==',
'operand2': 'null'
'operand2': {
'json_value': 'null'
}
}
]
}
Expand Down
16 changes: 9 additions & 7 deletions src/opserver/plugins/alarm_phyif_bandwidth/main.py
Expand Up @@ -7,7 +7,7 @@ class PhyifBandwidth(AlarmBase):
Physical Bandwidth usage anomaly as per VrouterStatsAgent.out_bps_ewm or VrouterStatsAgent.in_bps_ewm"""

def __init__(self):
AlarmBase.__init__(self, AlarmBase.SYS_WARN)
AlarmBase.__init__(self, AlarmBase.ALARM_MINOR)

def checkbw(self, stat, sname, vname, thresh):
alm = []
Expand All @@ -16,24 +16,26 @@ def checkbw(self, stat, sname, vname, thresh):
for k,val in stat.iteritems():
if val["sigma"] >= thresh:
match_list_o.append(AlarmMatch(json_operand1_value=json.dumps(
val["sigma"]), json_vars={
val["sigma"]), json_variables={
vname:json.dumps(k)}))
if val["sigma"] <= (-thresh):
match_list_u.append(AlarmMatch(json_operand1_value=json.dumps(
val["sigma"]), json_vars={
val["sigma"]), json_variables={
vname:json.dumps(k)}))

if len(match_list_o):
alm.append(AlarmAndList(and_list=[AlarmConditionMatch(
condition=AlarmCondition(operation=">=",
operand1=sname, operand2=json.dumps(thresh),
vars=[vname]),
operand1=sname, operand2=AlarmOperand2(
json_value=json.dumps(thresh)),
variables=[vname]),
match=match_list_o)]))
if len(match_list_u):
alm.append(AlarmAndList(and_list=[AlarmConditionMatch(
condition=AlarmCondition(operation="<=",
operand1=sname, operand2=json.dumps(-thresh),
vars=[vname]),
operand1=sname, operand2=AlarmOperand2(
json_value=json.dumps(-thresh)),
variables=[vname]),
match=match_list_u)]))
return alm

Expand Down

0 comments on commit 9677cd5

Please sign in to comment.