Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[change] NetJSON DeviceMonitoring compliance #2 #62

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'},
},
},
},
},
},
},
}
111 changes: 80 additions & 31 deletions netengine/backends/snmp/airos.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import binascii
import logging
from datetime import timedelta
from datetime import datetime

from .base import SNMP

Expand Down Expand Up @@ -98,15 +98,6 @@ def uptime(self):
"""
return int(self.get_value('1.3.6.1.2.1.1.3.0')) // 100

@property
def uptime_tuple(self):
"""
returns (days, hours, minutes)
"""
td = timedelta(seconds=self.uptime)

return td.days, td.seconds // 3600, (td.seconds // 60) % 60

@property
def interfaces_number(self):
"""
Expand Down Expand Up @@ -317,13 +308,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 @@ -384,6 +372,15 @@ def wireless_links(self):
final.append(result)
return final

@property
def local_time(self):
"""
returns the local time of the host device as a timestamp
"""
epoch = str(self.get('1.3.6.1.4.1.41112.1.4.8.1.0')[3][0][1])
timestamp = int(datetime.strptime(epoch, '%Y-%m-%d %H:%M:%S').timestamp())
return timestamp

@property
def RAM_total(self):
"""
Expand All @@ -400,23 +397,75 @@ def RAM_free(self):
free = self.get_value('1.3.6.1.4.1.10002.1.1.1.1.2.0')
return int(free)

@property
def RAM_buffered(self):
"""
Returns the buffered RAM of the device
"""
buffered = self.get_value('1.3.6.1.4.1.10002.1.1.1.1.3.0')
return int(buffered)

@property
purhan marked this conversation as resolved.
Show resolved Hide resolved
def RAM_cached(self):
"""
Returns the cached RAM of the device
"""
cached = self.get_value('1.3.6.1.4.1.10002.1.1.1.1.4.0')
return int(cached)

@property
def load(self):
"""
Returns an array with load average values respectively in the last
minute, in the last 5 minutes and in the last 15 minutes
"""
array = (self.next('1.3.6.1.4.1.10002.1.1.1.4.2.1.3'))[3]
one = int(array[0][0][1])
five = int(array[1][0][1])
fifteen = int(array[2][0][1])
return [one, five, fifteen]

@property
def SWAP_total(self):
"""
Returns the total SWAP of the device
"""
total = self.get_value('1.3.6.1.4.1.10002.1.1.1.2.1.0')
return int(total)

@property
def SWAP_free(self):
"""
Returns the free SWAP of the device
"""
free = self.get_value('1.3.6.1.4.1.10002.1.1.1.2.2.0')
return int(free)

@property
def resources_to_dict(self):
"""
returns an ordered dict with hardware resources information
"""
result = self._dict(
{
'load': self.load,
'memory': {
'total': self.RAM_total,
'buffered': self.RAM_buffered,
'free': self.RAM_free,
'cached': self.RAM_cached,
},
'swap': {'total': self.SWAP_total, 'free': self.SWAP_free},
}
)
return result

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, 'local_time': self.local_time},
'resources': self.resources_to_dict,
'interfaces': self.interfaces_to_dict,
'antennas': [],
'wireless_dbm': self.wireless_dbm,
'wireless_links': self.wireless_links,
'routing_protocols': None,
}
)
12 changes: 12 additions & 0 deletions netengine/backends/snmp/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'pysnmp library is not installed, install it with "pip install pysnmp"'
)

import binascii
import logging

from netengine.backends import BaseBackend
Expand Down Expand Up @@ -45,6 +46,17 @@ def _command(self):
"""
return cmdgen.CommandGenerator()

def _octet_to_mac(self, octet_mac):
"""
returns a valid mac address for a given octetstring
"""
mac_address = binascii.b2a_hex(octet_mac.encode()).decode()
if mac_address != '':
mac_address = ':'.join(
[mac_address[slice(i, i + 2)] for i in range(0, 12, 2) if i != '']
)
return mac_address

def _oid(self, oid):
"""
returns valid oid value to be passed to getCmd() or nextCmd()
Expand Down
Loading