Skip to content

Commit

Permalink
Merge pull request #2388 from hmpf/juniper-chassis-alarms
Browse files Browse the repository at this point in the history
Add support for Juniper CHASSIS and SYSTEM alerts
  • Loading branch information
johannaengland committed Jun 1, 2023
2 parents 33b5913 + dcff55b commit 2d2ef70
Show file tree
Hide file tree
Showing 17 changed files with 846 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Subject: No red alarms on {{ netbox }}
All red alarms on {{ netbox }} were resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No red alarms on {{ netbox }}.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Subject: {{ count }} red alarms on {{ netbox }}
The red alarm count on {{ netbox }} changed to {{ count }}.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ count }} red alarms on {{ netbox }}.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Subject: No yellow alarms on {{ netbox }}
All yellow alarms on {{ netbox }} were resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No yellow alarms on {{ netbox }}.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Subject: {{ count }} yellow alarms on {{ netbox }}
The yellow alarm count on {{ netbox }} changed to {{ count }}.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ count }} yellow alarms on {{ netbox }}.
3 changes: 2 additions & 1 deletion python/nav/etc/ipdevpoll.conf
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ staticroutes=
linkaggregate=
bgp=
poe=
juniperalarm=

[job_inventory]
#
Expand Down Expand Up @@ -148,7 +149,7 @@ description:
[job_statuscheck]
interval = 5m
intensity = 0
plugins = linkstate entity modules bgp poe psuwatch
plugins = linkstate entity modules bgp poe psuwatch juniperalarm
description:
This job runs plugins that check on the status of various internal components
of IP devices. The link state of interfaces, and the status/presence of
Expand Down
130 changes: 130 additions & 0 deletions python/nav/ipdevpoll/plugins/juniperalarm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#
# Copyright (C) 2023 Sikt
#
# This file is part of Network Administration Visualized (NAV).
#
# NAV is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 3 as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. You should have received a copy of the GNU General Public
# License along with NAV. If not, see <http://www.gnu.org/licenses/>.
#
"""Juniper chassis/system alarms"""

from twisted.internet import defer

from nav.enterprise.ids import VENDOR_ID_JUNIPER_NETWORKS_INC
from nav.event2 import EventFactory
from nav.ipdevpoll import Plugin, db
from nav.mibs.juniper_alarm_mib import JuniperAlarmMib
from nav.models.manage import NetboxInfo

YELLOW_EVENT = EventFactory(
source='ipdevpoll',
target='eventEngine',
event_type='juniperYellowAlarmState',
start_type='juniperYellowAlarmOn',
end_type='juniperYellowAlarmOff',
)
RED_EVENT = EventFactory(
source='ipdevpoll',
target='eventEngine',
event_type='juniperRedAlarmState',
start_type='juniperRedAlarmOn',
end_type='juniperRedAlarmOff',
)

INFO_KEY_NAME = "juniperalarm"


class JuniperChassisAlarm(Plugin):
"""Retrieves the number of red and yellow alarms in a chassis
This is done by attempting to retrieve the gauges in JUNIPER-ALARM-MIB:
* jnxYellowAlarmCount
* jnxRedAlarmCount
If the count is not zero, a start event for that color is sent. When the
count goes back to zero, an end-event is sent.
"""

RESTRICT_TO_VENDORS = [VENDOR_ID_JUNIPER_NETWORKS_INC]

@defer.inlineCallbacks
def handle(self):
self._logger.debug("Collecting any juniper led alarms")

mib = JuniperAlarmMib(self.agent)

last_yellow_count = yield db.run_in_thread(self._get_last_count, "yellow_count")
last_red_count = yield db.run_in_thread(self._get_last_count, "red_count")

current_yellow_count = yield mib.get_yellow_alarm_count()
current_red_count = yield mib.get_red_alarm_count()

if last_yellow_count != current_yellow_count:
if current_yellow_count:
yield db.run_in_thread(
self._post_yellow_alarm_count_non_zero, current_yellow_count
)
else:
yield db.run_in_thread(self._post_yellow_alarm_count_zero)

yield db.run_in_thread(
self._create_or_update_new_alarm_count,
current_yellow_count,
"yellow_count",
)

if last_red_count != current_red_count:
if current_red_count:
yield db.run_in_thread(
self._post_red_alarm_count_non_zero, current_red_count
)
else:
yield db.run_in_thread(self._post_red_alarm_count_zero)

yield db.run_in_thread(
self._create_or_update_new_alarm_count,
current_red_count,
"red_count",
)

def _get_last_count(self, variable: str):
count = getattr(
NetboxInfo.objects.filter(netbox__id=self.netbox.id)
.filter(key=INFO_KEY_NAME)
.filter(variable=variable)
.first(),
"value",
None,
)
if count != None and count.isdigit():
return int(count)

def _post_yellow_alarm_count_non_zero(self, count: int):
YELLOW_EVENT.start(netbox=self.netbox.id, varmap={"count": count}).save()

def _post_yellow_alarm_count_zero(self):
YELLOW_EVENT.end(netbox=self.netbox.id).save()

def _post_red_alarm_count_non_zero(self, count: int):
RED_EVENT.start(netbox=self.netbox.id, varmap={"count": count}).save()

def _post_red_alarm_count_zero(self):
RED_EVENT.end(netbox=self.netbox.id).save()

def _create_or_update_new_alarm_count(self, count: int, variable: str):
object, _ = NetboxInfo.objects.get_or_create(
netbox_id=self.netbox.id,
key=INFO_KEY_NAME,
variable=variable,
)
object.value = count
object.save()
44 changes: 44 additions & 0 deletions python/nav/mibs/juniper_alarm_mib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#
# Copyright (C) 2023 Sikt
#
# This file is part of Network Administration Visualized (NAV).
#
# NAV is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 3 as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License
# along with NAV. If not, see <http://www.gnu.org/licenses/>.
#
"""JUNIPER-ALARM-MIB MibRetriever"""
from twisted.internet import defer

from nav.oids import OID
from nav.smidumps import get_mib
from nav.mibs.mibretriever import MibRetriever


class JuniperAlarmMib(MibRetriever):
"""JUNIPER-ALARM-MIB MibRetriever"""

mib = get_mib("JUNIPER-ALARM-MIB")

def get_yellow_alarm_count(self):
"""Tries to get a yellow alarm count from a Juniper device"""
return self._get_alarm_count("jnxYellowAlarmCount")

def get_red_alarm_count(self):
"""Tries to get a red alarm count from a Juniper device"""
return self._get_alarm_count("jnxRedAlarmCount")

@defer.inlineCallbacks
def _get_alarm_count(self, oid):
count = yield self.get_next(oid)
try:
count = int(count) or 0
except (ValueError, TypeError):
count = 0
defer.returnValue(count)
12 changes: 12 additions & 0 deletions python/nav/models/sql/changes/sc.05.07.0001.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
INSERT INTO eventtype (eventtypeid,eventtypedesc,stateful) VALUES
('juniperYellowAlarmState','Tells us if a Juniper device has any open yellow alarms.','y');
INSERT INTO eventtype (eventtypeid,eventtypedesc,stateful) VALUES
('juniperRedAlarmState','Tells us if a Juniper device has any open red alarms.','y');
INSERT INTO alerttype (eventtypeid,alerttype,alerttypedesc) VALUES
('juniperYellowAlarmState','juniperYellowAlarmOn','The Juniper device has some yellow alarms.');
INSERT INTO alerttype (eventtypeid,alerttype,alerttypedesc) VALUES
('juniperYellowAlarmState','juniperYellowAlarmOff','The Juniper device has no yellow alarms.');
INSERT INTO alerttype (eventtypeid,alerttype,alerttypedesc) VALUES
('juniperRedAlarmState','juniperRedAlarmOn','The Juniper device has some red alarms.');
INSERT INTO alerttype (eventtypeid,alerttype,alerttypedesc) VALUES
('juniperRedAlarmState','juniperRedAlarmOff','The Juniper device has no red alarms.');

0 comments on commit 2d2ef70

Please sign in to comment.