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 1 commit
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
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ Contents:
.. toctree::
:maxdepth: 2

/topics/backends/snmp
/topics/usage
/topics/snmp

Indices and tables
==================
Expand Down
149 changes: 149 additions & 0 deletions docs/source/topics/backends/snmp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@

************
SNMP backend
************

SNMP
====

SNMP (Simple Network Management Protocol) is a network protocol very useful for retrieving info from a device.
All the information is retrieved by using codes called MIBs. All MIBs have a tree-like structure, every main information is the root and by adding more detail to the info
the tree gains more depth.
Obviously, by getting the smallest MIB which is "1" or simply " . " one can get all the tree.

The base SNMP backend contains the following methods (some internal methods are not documented and are subject to change in the future):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can avoid explaining what SNMP is, we assume peopel using this library will know.

We can however include information about how all the data is retrieved and give a few hints on how to use the base backend to create new SNMP backends for other systems (eg: indicate the python path for the base backend and explain anything important regarding it).


+--------------+------------------------------------------------------------------------------------------------------------------------------------------+
| **to_dict** | Returns a dict containing monitoring information depending on the type of the device. |
| | It follows the `NetJSON Devicemonitoring <https://netjson.org/rfc.html#name-devicemonitoring>`_ spec |
+--------------+------------------------------------------------------------------------------------------------------------------------------------------+
| **to_json** | Calls the `to_dict` method and returns a JSON string of the dict |
+--------------+------------------------------------------------------------------------------------------------------------------------------------------+
| **validate** | Checks if connection with the device is working and raises `NetengineError` in case something is wrong |
+--------------+------------------------------------------------------------------------------------------------------------------------------------------+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to do the same here and drop the table syntax which is painful to maintain


Initializing an SNMP backend class requires the following arguments:

+---------------+---------------------------------------------------------------------+
| **host** | Management ip or hostname of the device |
+---------------+---------------------------------------------------------------------+
| **community** | Community string for the SNMP connection. Default value is 'public' |
+---------------+---------------------------------------------------------------------+
| **agent** | Agent string for the SNMP connection |
+---------------+---------------------------------------------------------------------+
| **port** | Port for the SNMP connection. Default value is `161` |
+---------------+---------------------------------------------------------------------+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these parameters all mandatory?
Is there any default value for any parameter?
Let's make this explicit.
There's no need to write this table, sphinx has automations we can use to autodocument these things.
Please use it!
Refer to the netjsonconfig documentation for examples:
http://netjsonconfig.openwisp.org/en/latest/backends/openwrt.html#initialization

I mean this:

Screenshot from 2021-08-19 17-31-32

See the source for more info: https://raw.githubusercontent.com/openwisp/netjsonconfig/master/docs/source/backends/openwrt.rst

The doc text is embedded in a docstring in the method itself.

This is a good practice, the docstring is also shown in some rich shells (bpython should show it, not sure about ipython).


The SNMP backend provides support for 2 firmwares:
* AirOS
* OpenWRT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please list OpenWrt first. Please also link their respective pages


.. note::

The data collected by Netengine is dependant on the OIDs available on your device. Some proprietary manufacturers may not
provide the same information as others.

*****
AirOS
*****

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as in netjsonconfig, I suggest to make this a dedicated page, which should point to the base snmp page for the general concepts.

Some information regarding methods can be duplicated (no problem with this if we use autodoc).

With AirOS, Netengine is able to collect the following information which is returned in the
`NetJSON Devicemonitoring <https://netjson.org/rfc.html#name-devicemonitoring>`_ format:

+------------+------------------------------------------------------------------------------------------------------------+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please let's switch from table sytnax which is painful to maintain to simple headings and list after headings.

| general | - uptime: uptime of the device in seconds |
| | - local_time: local time of the device in timestamp |
+------------+------------------------------------------------------------------------------------------------------------+
| resources | - load: array containing average load on the cpu in the past minute, 5 minutes and 15 minutes respectively |
| | - memory: |
| | - total: total memory in bytes |
| | - buffered: buffered memory in bytes |
| | - free: free memory in bytes |
| | - cached: cached memory in bytes |
| | - swap: |
| | - total: total swap storage in bytes |
| | - free: free swap storage in bytes |
+------------+------------------------------------------------------------------------------------------------------------+
| interfaces | Each interface is listed with the following information: |
| | |
| | - name |
| | - type |
| | - statistics: |
| | |
| | - rx_bytes |
| | - tx_bytes |
+------------+------------------------------------------------------------------------------------------------------------+

AirOS example
=============

::

from netengine.backends.snmp import AirOS
device = AirOS("10.40.0.130")
device.name
'RM5PomeziaSNode'
device.uptime_tuple
(121, 0, 5) # a tuple containing device uptime hours, mins and seconds

We have just called two simple properties on **device**, but we can ask **device** for more specific values or portions of the SNMP tree not included in the API, just type::
device.next("1.3.6")

Otherwise, if you want simply a value of the tree just type::
device.get_value("oid_you_want_to_ask_for")
Copy link
Member

@nemesifier nemesifier Aug 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these methods are not documented above so why are we showing them in the example?

I guess we can document (and keep public) next and get_value, but I would avoid documenting uptime_tuple because it would not be consistent with advising to use to_netjson and make all other internal methods private.


To collect the whole json::
device.to_json()

*******
OpenWRT
*******

With OpenWRT, Netengine is able to collect the following information which is returned in the
`NetJSON Devicemonitoring <https://netjson.org/rfc.html#name-devicemonitoring>`_ format:

+------------+----------------------------------------------------------+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please let's switch from table sytnax which is painful to maintain to simple headings and list after headings.

| general | - uptime: uptime of the device in seconds |
| | - local_time: local time of the device in timestamp |
+------------+----------------------------------------------------------+
| resources | - cpus: number of cpus on the device |
| | - memory: |
| | - total: total memory in bytes |
| | - shared: shared memory in bytes |
| | - used: used memory in bytes |
| | - free: free memory in bytes |
| | - cached: cached memory in bytes |
| | - swap: |
| | - total: total swap storage in bytes |
| | - free: free swap storage in bytes |
+------------+----------------------------------------------------------+
| interfaces | Each interface is listed with the following information: |
| | |
| | - name: name of the interface (example: "eth0") |
| | - statistics: |
| | |
| | - mac |
| | - type |
| | - up |
| | - rx_bytes |
| | - tx_bytes |
| | - mtu |
| | - addresses: |
| | |
| | - family |
| | - address |
| | - mask |
+------------+----------------------------------------------------------+
| neighbors | Each neighbor is listed with the following information: |
| | - mac: mac address of the neighbor |
| | - state: state of the neighbor (REACHABLE/STALE/DELAY) |
| | - interface: interface of the neighbor |
| | - ip: ip address of the neighbor |
+------------+----------------------------------------------------------+

OpenWRT example
===============

The same instructions typed above can be applied to OpenWRT itself, just remember to import the correct firmware by typing::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not a firmware, it's a backend.


from netengine.backends.snmp import OpenWRT
50 changes: 0 additions & 50 deletions docs/source/topics/snmp.rst

This file was deleted.