Skip to content

Commit

Permalink
Merge pull request #68 from johannaengland/juniper-check-change
Browse files Browse the repository at this point in the history
Only post juniper alarm events on changed state
  • Loading branch information
lunkwill42 authored Sep 11, 2023
2 parents 9915be1 + 05445a8 commit 0ae693c
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 27 deletions.
36 changes: 24 additions & 12 deletions src/zino/tasks/juniperalarmtask.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ async def run(self):
except TypeError:
return

device_state.alarms = {
"yellow": yellow_alarm_count,
"red": red_alarm_count,
}
if not device_state.alarms:
device_state.alarms = {
"yellow": 0,
"red": 0,
}

self.create_alarm_event(color="yellow", alarm_count=yellow_alarm_count)
self.create_alarm_event(color="red", alarm_count=red_alarm_count)
if device_state.alarms["yellow"] != yellow_alarm_count:
device_state.alarms["yellow"] = yellow_alarm_count
self.create_alarm_event(color="yellow", alarm_count=yellow_alarm_count)

if device_state.alarms["red"] != red_alarm_count:
device_state.alarms["red"] = red_alarm_count
self.create_alarm_event(color="red", alarm_count=red_alarm_count)

async def _get_juniper_alarms(self):
snmp = SNMP(self.device)
Expand All @@ -38,13 +44,19 @@ async def _get_juniper_alarms(self):
if red_alarm_count:
red_alarm_count = red_alarm_count.value

if type(yellow_alarm_count) is not int or type(red_alarm_count) is not int:
if not isinstance(yellow_alarm_count, int) or not isinstance(red_alarm_count, int):
_logger.error(
"Device %s returns alarm count not of type int, type yellow alarm count: %s, type red alarm count: %s",
"Device %s returns alarm count not of type int. "
"Yellow alarm count: type %s. Red alarm count: type %s.",
self.device.name,
type(yellow_alarm_count),
type(red_alarm_count),
)
_logger.debug(
"Yellow alarm count: value %r. Red alarm count: value %r.",
yellow_alarm_count,
red_alarm_count,
)
raise TypeError

return yellow_alarm_count, red_alarm_count
Expand All @@ -58,7 +70,7 @@ def create_alarm_event(self, color: Literal["yellow", "red"], alarm_count: int):
if created:
alarm_event.state = EventState.OPEN
alarm_event.add_history("Change state to Open")
if alarm_event.alarm_count != alarm_count:
old_alarm_count = alarm_event.alarm_count
alarm_event.alarm_count = alarm_count
alarm_event.add_log(f"{self.device.name} {color} alarms went from {old_alarm_count} to {alarm_count}")

old_alarm_count = alarm_event.alarm_count
alarm_event.alarm_count = alarm_count
alarm_event.add_log(f"{self.device.name} {color} alarms went from {old_alarm_count} to {alarm_count}")
2 changes: 2 additions & 0 deletions tests/snmp_fixtures/juniper-alarm-zero.snmprec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1.3.6.1.4.1.2636.3.4.2.2.2.0|66|0
1.3.6.1.4.1.2636.3.4.2.3.2.0|66|0
2 changes: 1 addition & 1 deletion tests/snmp_fixtures/juniper-alarm.snmprec
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
1.3.6.1.4.1.2636.3.4.2.2.2.0|66|0
1.3.6.1.4.1.2636.3.4.2.2.2.0|66|1
1.3.6.1.4.1.2636.3.4.2.3.2.0|66|2
85 changes: 71 additions & 14 deletions tests/tasks/test_juniperalarmtask.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

class TestJuniperalarmTask:
@pytest.mark.asyncio
async def test_task_runs_without_errors(self, snmpsim, juniper_alarm_task):
async def test_task_runs_without_errors(self, juniper_alarm_task):
assert (await juniper_alarm_task.run()) is None

@pytest.mark.asyncio
async def test_task_does_nothing_for_non_juniper_device(self, snmpsim, juniper_alarm_task):
async def test_task_does_nothing_for_non_juniper_device(self, juniper_alarm_task):
task = juniper_alarm_task
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 11
Expand All @@ -22,7 +22,7 @@ async def test_task_does_nothing_for_non_juniper_device(self, snmpsim, juniper_a
assert device_state.alarms is None

@pytest.mark.asyncio
async def test_task_does_nothing_for_non_int_result(self, snmpsim, snmp_test_port):
async def test_task_does_nothing_for_non_int_result(self, snmp_test_port):
device = PollDevice(
name="buick.lab.example.org",
address="127.0.0.1",
Expand All @@ -38,34 +38,34 @@ async def test_task_does_nothing_for_non_int_result(self, snmpsim, snmp_test_por
assert device_state.alarms is None

@pytest.mark.asyncio
async def test_task_saves_alarm_count_in_device_state(self, snmpsim, juniper_alarm_task):
async def test_task_saves_alarm_count_in_device_state(self, juniper_alarm_task):
task = juniper_alarm_task
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 2636

await task.run()

assert device_state.alarms
assert device_state.alarms["yellow"] == 0
assert device_state.alarms["yellow"] == 1
assert device_state.alarms["red"] == 2

@pytest.mark.asyncio
async def test_task_overrides_alarm_count_in_device_state(self, snmpsim, juniper_alarm_task):
async def test_task_overrides_alarm_count_in_device_state(self, juniper_alarm_task):
task = juniper_alarm_task
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 2636
device_state.alarms = {
"yellow": "1",
"red": "3",
"yellow": 2,
"red": 3,
}

await task.run()

assert device_state.alarms["yellow"] == 0
assert device_state.alarms["yellow"] == 1
assert device_state.alarms["red"] == 2

@pytest.mark.asyncio
async def test_task_creates_alarm_events(self, snmpsim, juniper_alarm_task):
async def test_task_creates_both_alarm_events_on_both_counts_changed(self, juniper_alarm_task):
task = juniper_alarm_task
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 2636
Expand All @@ -77,28 +77,85 @@ async def test_task_creates_alarm_events(self, snmpsim, juniper_alarm_task):

assert yellow_event
assert red_event
assert yellow_event.alarm_count == 0
assert yellow_event.alarm_count == 1
assert red_event.alarm_count == 2

@pytest.mark.asyncio
async def test_task_updates_alarm_events(self, snmpsim, juniper_alarm_task):
async def test_task_creates_one_alarm_event_on_one_count_changed(self, juniper_alarm_task):
task = juniper_alarm_task
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 2636
device_state.alarms = {
"yellow": 1,
"red": 0,
}

await task.run()

yellow_event = task.state.events.get(device_name=task.device.name, port="yellow", event_class=AlarmEvent)
red_event = task.state.events.get(device_name=task.device.name, port="red", event_class=AlarmEvent)

assert not yellow_event
assert red_event
assert red_event.alarm_count == 2

@pytest.mark.asyncio
async def test_task_updates_alarm_events(self, juniper_alarm_task):
task = juniper_alarm_task
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 2636
yellow_event, _ = task.state.events.get_or_create_event(
device_name=task.device.name, port="yellow", event_class=AlarmEvent
)
yellow_event.alarm_count = 1
yellow_event.alarm_count = 2
red_event, _ = task.state.events.get_or_create_event(
device_name=task.device.name, port="red", event_class=AlarmEvent
)
red_event.alarm_count = 3

await task.run()

assert yellow_event.alarm_count == 0
assert yellow_event.alarm_count == 1
assert red_event.alarm_count == 2

@pytest.mark.asyncio
async def test_task_does_not_create_alarm_events_on_unchanged_alarm_count(self, juniper_alarm_task):
task = juniper_alarm_task
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 2636
device_state.alarms = {
"yellow": 1,
"red": 2,
}

await task.run()

yellow_event = task.state.events.get(device_name=task.device.name, port="yellow", event_class=AlarmEvent)
red_event = task.state.events.get(device_name=task.device.name, port="red", event_class=AlarmEvent)

assert not yellow_event
assert not red_event

@pytest.mark.asyncio
async def test_task_does_not_create_alarm_events_on_alarm_count_zero_on_first_run(self, snmp_test_port):
device = PollDevice(
name="buick.lab.example.org",
address="127.0.0.1",
community="juniper-alarm-zero",
port=snmp_test_port,
)
state = ZinoState()
task = JuniperAlarmTask(device, state)
device_state = task.state.devices.get(device_name=task.device.name)
device_state.enterprise_id = 2636
await task.run()

yellow_event = task.state.events.get(device_name=task.device.name, port="yellow", event_class=AlarmEvent)
red_event = task.state.events.get(device_name=task.device.name, port="red", event_class=AlarmEvent)

assert not yellow_event
assert not red_event


@pytest.fixture()
def juniper_alarm_task(snmpsim, snmp_test_port):
Expand Down

0 comments on commit 0ae693c

Please sign in to comment.