Skip to content

Commit

Permalink
[change] NetJSON DeviceMonitoring compliance #2
Browse files Browse the repository at this point in the history
Closes #2
  • Loading branch information
purhan committed Jun 5, 2021
1 parent 11f8ea4 commit d46b568
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 53 deletions.
152 changes: 152 additions & 0 deletions netengine/backends/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# NetJSON DeviceMonitoring schema,
# https://github.com/netjson/netjson/blob/master/schema/device-monitoring.json
schema = {
'$schema': 'http://json-schema.org/draft-07/schema#',
'$id': 'https://raw.githubusercontent.com/netjson/netjson/master/schema/device-monitoring.json',
'title': 'NetJSON Device Monitoring',
'description': 'Monitoring information sent by a device.',
'type': 'object',
'additionalProperties': True,
'required': ['type'],
'properties': {
'type': {'type': 'string', 'enum': ['DeviceMonitoring']},
'general': {
'type': 'object',
'title': 'General',
'additionalProperties': True,
'properties': {
'local_time': {'type': 'integer'},
'uptime': {'type': 'integer'},
},
},
'resources': {
'type': 'object',
'title': 'Resources',
'additionalProperties': True,
'properties': {
'load': {
'type': 'array',
'items': {'type': 'number', 'minItems': 3, 'maxItems': 3},
},
'memory': {
'id': 'memory',
'type': 'object',
'properties': {
'total': {'type': 'integer'},
'free': {'type': 'integer'},
'buffered': {'type': 'integer'},
'cache': {'type': 'integer'},
},
},
'swap': {
'type': 'object',
'properties': {
'total': {'type': 'integer'},
'free': {'type': 'integer'},
},
},
'connections': {
'type': 'object',
'properties': {
'ipv4': {
'type': 'object',
'properties': {
'tcp': {'type': 'integer'},
'udp': {'type': 'integer'},
},
},
'ipv6': {
'type': 'object',
'properties': {
'tcp': {'type': 'integer'},
'udp': {'type': 'integer'},
},
},
},
},
'processes': {
'type': 'object',
'properties': {
'running': {'type': 'integer'},
'sleeping': {'type': 'integer'},
'blocked': {'type': 'integer'},
'zombie': {'type': 'integer'},
'stopped': {'type': 'integer'},
'paging': {'type': 'integer'},
},
},
'cpu': {
'type': 'object',
'properties': {
'frequency': {'type': 'integer'},
'user': {'type': 'integer'},
'system': {'type': 'integer'},
'nice': {'type': 'integer'},
'idle': {'type': 'integer'},
'iowait': {'type': 'integer'},
'irq': {'type': 'integer'},
'softirq': {'type': 'integer'},
},
},
'flash': {
'type': 'object',
'properties': {
'total': {'type': 'integer'},
'free': {'type': 'integer'},
},
},
'storage': {
'type': 'object',
'properties': {
'total': {'type': 'integer'},
'free': {'type': 'integer'},
},
},
},
},
'interfaces': {
'type': 'array',
'title': 'Interfaces',
'uniqueItems': True,
'additionalItems': True,
'items': {
'type': 'object',
'title': 'Interface',
'additionalProperties': True,
'required': ['name'],
'properties': {
'name': {'type': 'string'},
'uptime': {'type': 'integer'},
'statistics': {
'type': 'object',
'properties': {
'collisions': {'type': 'integer'},
'rx_frame_errors': {'type': 'integer'},
'tx_compressed': {'type': 'integer'},
'multicast': {'type': 'integer'},
'rx_length_errors': {'type': 'integer'},
'tx_dropped': {'type': 'integer'},
'rx_bytes': {'type': 'integer'},
'rx_missed_errors': {'type': 'integer'},
'tx_errors': {'type': 'integer'},
'rx_compressed': {'type': 'integer'},
'rx_over_errors': {'type': 'integer'},
'tx_fifo_errors': {'type': 'integer'},
'rx_crc_errors': {'type': 'integer'},
'rx_packets': {'type': 'integer'},
'tx_heartbeat_errors': {'type': 'integer'},
'rx_dropped': {'type': 'integer'},
'tx_aborted_errors': {'type': 'integer'},
'tx_packets': {'type': 'integer'},
'rx_errors': {'type': 'integer'},
'tx_bytes': {'type': 'integer'},
'tx_window_errors': {'type': 'integer'},
'rx_fifo_errors': {'type': 'integer'},
'tx_carrier_errors': {'type': 'integer'},
},
},
},
},
},
},
}
30 changes: 9 additions & 21 deletions netengine/backends/snmp/airos.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,10 @@ def interfaces_to_dict(self):
result = self._dict(
{
'name': self.interfaces_MAC[i]['name'],
'type': self.interfaces_type[i]['type'],
'mac_address': self.interfaces_MAC[i]['mac_address'],
'rx_bytes': int(self.interfaces_bytes[i]['rx']),
'tx_bytes': int(self.interfaces_bytes[i]['tx']),
'state': self.interfaces_state[i]['state'],
'mtu': int(self.interfaces_mtu[i]['mtu']),
'speed': int(self.interfaces_speed[i]['speed']),
'statistics': {
'rx_bytes': int(self.interfaces_bytes[i]['rx']),
'tx_bytes': int(self.interfaces_bytes[i]['tx']),
},
}
)
results.append(result)
Expand Down Expand Up @@ -403,20 +400,11 @@ def RAM_free(self):
def to_dict(self):
return self._dict(
{
'name': self.name,
'type': 'radio',
'os': self.os[0],
'os_version': self.os[1],
'manufacturer': self.manufacturer,
'model': self.model,
'RAM_total': self.RAM_total,
'RAM_free': self.RAM_free,
'uptime': self.uptime,
'uptime_tuple': self.uptime_tuple,
'type': 'DeviceMonitoring',
'general': {'uptime': self.uptime,},
'resources': {
'memory': {'total': self.RAM_total, 'free': self.RAM_free,},
},
'interfaces': self.interfaces_to_dict,
'antennas': [],
'wireless_dbm': self.wireless_dbm,
'wireless_links': self.wireless_links,
'routing_protocols': None,
}
)
26 changes: 5 additions & 21 deletions netengine/backends/snmp/openwrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,15 +368,7 @@ def interfaces_to_dict(self):
result = self._dict(
{
'name': name,
'type': if_type,
'mac_address': mac_address,
'ip_address': ip_address,
'netmask': netmask,
'rx_bytes': rx_bytes,
'tx_bytes': tx_bytes,
'state': state,
'mtu': mtu,
'speed': speed,
'statistics': {'rx_bytes': rx_bytes, 'tx_bytes': tx_bytes,},
}
)
results.append(result)
Expand All @@ -392,17 +384,9 @@ def RAM_total(self):
def to_dict(self):
return self._dict(
{
'name': self.name,
'type': 'radio',
'os': self.os[0],
'os_version': self.os[1],
'manufacturer': self.manufacturer,
'model': None,
'RAM_total': self.RAM_total,
'uptime': self.uptime,
'uptime_tuple': self.uptime_tuple,
'interfaces': self.get_interfaces(),
'antennas': [],
'routing_protocols': None,
'type': 'DeviceMonitoring',
'general': {'uptime': self.uptime,},
'resources': {'memory': {'total': self.RAM_total,}},
'interfaces': self.interfaces_to_dict,
}
)
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ coverage~=5.5
sphinx~=4.0.2
openwisp-utils[qa]~=0.7.4
pylinkvalidator~=0.3.0
jsonschema~=3.2.0
8 changes: 4 additions & 4 deletions tests/static/test-airos-snmp.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
"1.2.840.10036.3.1.2.1.4.5": "XM.ar7240.v5.5.12536.120406.1455",
"1.2.840.10036.3.1.2.1.3.5": "NanoStation Loco M2",
"1.3.6.1.2.1.2.2.1.2.1": "\\xd4\\xa0*",
"1.3.6.1.2.1.2.2.1.2.2": "\\xd4\\xa0*",
"1.3.6.1.2.1.2.2.1.2.3": "\\xd4\\xa0*",
"1.3.6.1.2.1.2.2.1.2.4": "\\xd4\\xa0*",
"1.3.6.1.2.1.2.2.1.2.5": "\\xd4\\xa0*",
"1.3.6.1.2.1.2.2.1.2.2": "\\xd4\\xb0*",
"1.3.6.1.2.1.2.2.1.2.3": "\\xd4\\xc0*",
"1.3.6.1.2.1.2.2.1.2.4": "\\xd4\\xd0*",
"1.3.6.1.2.1.2.2.1.2.5": "\\xd4\\xe0*",
"1.3.6.1.2.1.2.2.1.6.1": "\b\u0000''�\u0010\u0014",
"1.3.6.1.2.1.2.2.1.6.2": "\b\u0000''�\u0010\u0000",
"1.3.6.1.2.1.2.2.1.6.3": "\b\u0000''�\u0010\u0015",
Expand Down
10 changes: 8 additions & 2 deletions tests/test_snmp/test_airos.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import json
import unittest
from unittest.mock import patch

from jsonschema import validate
from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.smi.error import NoSuchObjectError

from netengine.backends.schema import schema
from netengine.backends.snmp import AirOS
from netengine.exceptions import NetEngineError

Expand Down Expand Up @@ -142,15 +145,18 @@ def test_to_dict(self):
)
self.assertTrue(isinstance(self.device.to_dict(), dict))

def test_manufacturer_to_dict(self):
def test_netjson_compliance(self):
with self.nextcmd_patcher as np:
SpyMock._update_patch(
np,
_mock_side_effect=lambda *args: self._get_mocked_wireless_links(
data=args
),
)
self.assertIsNotNone(self.device.to_dict()['manufacturer'])
device_dict = self.device.to_dict()
device_json = self.device.to_json()
validate(instance=device_dict, schema=schema)
validate(instance=json.loads(device_json), schema=schema)

def test_manufacturer(self):
with self.nextcmd_patcher:
Expand Down
14 changes: 10 additions & 4 deletions tests/test_snmp/test_openwrt.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import json
import unittest
from unittest.mock import patch

from jsonschema import validate
from pysnmp.entity.rfc3413.oneliner import cmdgen

from netengine.backends.schema import schema
from netengine.backends.snmp import OpenWRT

from ..settings import settings
Expand Down Expand Up @@ -94,17 +97,20 @@ def test_RAM_total(self):

def test_to_dict(self):
with self.nextcmd_patcher as p:
SpyMock._update_patch(p, _mock_return_value=[0, 0, 0, [[[0, 1]]] * 5])
SpyMock._update_patch(p, _mock_return_value=[0, 0, 0, []])
device_dict = self.device.to_dict()
self.assertTrue(isinstance(device_dict, dict))
self.assertEqual(
len(device_dict['interfaces']), len(self.device.get_interfaces()),
)

def test_manufacturer_to_dict(self):
def test_netjson_compliance(self):
with self.nextcmd_patcher as p:
SpyMock._update_patch(p, _mock_return_value=[0, 0, 0, [[[0, 1]]] * 5])
self.assertIsNotNone(self.device.to_dict()['manufacturer'])
SpyMock._update_patch(p, _mock_return_value=[0, 0, 0, []])
device_dict = self.device.to_dict()
device_json = self.device.to_json()
validate(instance=device_dict, schema=schema)
validate(instance=json.loads(device_json), schema=schema)

def tearDown(self):
patch.stopall()
7 changes: 6 additions & 1 deletion tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ def _get_mocked_wireless_links(data):
'1.3.6.1.4.1.14988.1.1.1.2.1': [0, 0, 0, [[[0, 0], 0]] * 28],
'1.3.6.1.4.1.14988.1.1.1.2.1.3': [0, 0, 0, [0, 0]],
'1.3.6.1.4.1.14988.1.1.1.2.1.3.0': [None, 0, 0, []],
'1.3.6.1.2.1.1.9.1.1': [0, 0, 0, [[[0, 1]]] * 5],
'1.3.6.1.2.1.1.9.1.1': [
0,
0,
0,
[[[0, 1]], [[0, 2]], [[0, 3]], [[0, 4]], [[0, 5]]],
],
}
return return_data[oid]

0 comments on commit d46b568

Please sign in to comment.