Scripts Reference¶
Script Implementation¶
The implementation of interfaces and interaction with equipment is carried out in script files. By inheriting the class noc.core.script.base.BaseScript
, the logic for working with equipment and normalizing received data for transmission to NOC is implemented in these files.
List of Scripts¶
Script Name | Interface | Generic | Purpose |
---|---|---|---|
get_version | IGetVersion | Retrieve the device's version and platform information | |
get_capabilities | IGetCapabilities | Collect information about the device's functional support (protocols) | |
get_config | IGetConfig | Retrieve device configuration | |
get_interfaces | IGetInterfaces | Request a list of interfaces from the device | |
get_inventory | IGetInventory | Collect information about the device's inventory | |
get_chassis_id | IGetChassisid | Retrieve the device's chassis MAC address | |
get_fqdn | IGetFqdn | Retrieve the device's hostname | |
get_mac_address_table | IGetMACAddressTable | Retrieve the device's MAC address table | |
get_arp | IGetArp | Retrieve the device's ARP table | |
get_cdp_neighbors | IGetCDPNeighbors | Retrieve the CDP protocol neighbor table | |
get_fdp_neighbors | IGetFDPNeighbors | Retrieve the FDP protocol neighbor table | |
get_huawei_ndp_neighbors | IGetHuaweiNDPNeighbors | Retrieve the Huawei NDP protocol neighbor table | |
get_lacp_neighbors | IGetLACPNeighbors | Retrieve the LACP protocol neighbor table | |
get_lldp_neighbors | IGetLLDPNeighbors | Retrieve the LLDP protocol neighbor table | |
get_udld_neighbors | IGetUDLDNeighbors | Retrieve the UDLD protocol neighbor table |
Script Structure¶
Example script file:
from noc.core.script.base import BaseScript
from noc.sa.interfaces.igetversion import IGetVersion
import re
class Script(BaseScript):
name = "Huawei.VRP.get_version"
cache = True
interface = IGetVersion
def execute_cli(self, **kwargs):
v = self.cli("display version")
...
def execute_snmp(self, **kwargs):
v = self.snmp.get("1.XXXX")
...
Script Structure¶
- Import Area: In this section, we import the script's base class (line 1) and the interface implemented by the script (line 2). This is also where you can import any necessary modules for the script, like the regular expression support module (line 3).
- After importing the required modules, we declare the
Script
class, inheriting it from the base class (BaseScript
). We specify the full script name, interface, and whether caching the execution result is needed. - Cache: Setting it to
True
caches the script's execution result. This can be useful when calling the script from other scripts viaself.scripts.<script_name>()
. - Methods for interacting with equipment -
execute_snmp()
andexecute_cli()
. The order of execution is determined by priority. You can set the priority in the ManagedObject settings. - If there's an
execute()
method, execution always starts with it, even ifexecute_snmp()
orexecute_cli()
are present. This can be used to intervene in determining the execution priority.
Interaction with Equipment¶
The base class noc.core.script.base.BaseScript
includes methods for working with equipment:
CLI¶
A text-based interface for working with equipment, implemented via Telnet
or SSH
. The BaseScript.cli
method allows you to execute commands on the equipment. Commands are passed as text arguments, and the output of the requested command is returned as a text string. Further handling is the responsibility of the developer.
- Method:
noc.core.script.base.BaseScript.cli
In case of a command execution error, an exception (Exception
) may be raised: - CLISyntaxError
: Command error, determined based on the pattern_syntax_error
setting. - CLIOperationError
: Command error, determined based on the pattern_operation_error
setting.
You can catch these exceptions and use them to alter the script's behavior.
SNMP¶
The methods allow you to perform SNMP requests to the equipment, with the OID (Object Identifier) as an argument. The result is returned as a number or a string.
::: noc.core.script.snmp.base:SNMP.get selection: docstring_style: restructured-text rendering: show_root_heading: true heading_level: 4 show_category_heading: true
::: noc.core.script.snmp.base:SNMP.getnext selection: docstring_style: restructured-text rendering: show_root_heading: true heading_level: 4 show_category_heading: true
To simplify the SNMP interaction you may use mib
::: noc.core.script.snmp.base:SNMP.get_table selection: docstring_style: restructured-text rendering: show_root_heading: true heading_level: 4 show_category_heading: true
::: noc.core.script.snmp.base:SNMP.get_tables selection: docstring_style: restructured-text rendering: show_root_heading: true heading_level: 4 show_category_heading: true
To facilitate working with SNMP, there is a built-in "mib" module that allows you to convert textual names into corresponding OIDs. To do this, the name must be present in the "cmibs" database, which is located in <base_noc>/cmibs
. Here's how to add a MIB to "cmibs":
Prepare the MIB file: Make sure you have a text file with a
.mib
extension containing the MIB definitions. This file can be an official MIB provided by the device manufacturer or a custom MIB that you want to use.Create a directory for the MIB: Inside the
<base_noc>/cmibs
directory, create a new directory with a name that corresponds to the MIB identifier, such as1.3.6.1.4.1.9.2
.Copy the MIB file: Place the MIB file into the created directory. Ensure that the file has the correct name, matching the MIB identifier. For example, if the MIB identifier is
1.3.6.1.4.1.9.2
, the filename should be1.3.6.1.4.1.9.2.mib
.Update the MIB database: Execute the
./noc mib update
command from the command line in the NOC directory. This command updates the MIB database and makes the new MIBs available for use.
You can now use textual names from this MIB in your SNMP queries using the mib
module. The mib
module allows you to perform the conversion from a textual name to the corresponding OID using the mib.resolve(name)
function.
Here is an example of how to use the mib
module:
from noc.core.mib import mib
mib["BRIDGE-MIB::dot1dBasePortIfIndex"]
: '1.3.6.1.2.1.17.1.4.1.2'
mib["BRIDGE-MIB::dot1dBasePortIfIndex", 100]
: '1.3.6.1.2.1.17.1.4.1.2.100'
To interpret SNMP data stored as OctetString correctly, you may need to define the interpretation function through the display_hints argument. Built-in functions for this purpose are available in the noc.core.snmp.render module. By using these functions, you can convert raw OctetString data into human-readable format, making it easier to work with SNMP data.
from noc.core.script.base import BaseScript
from noc.core.mib import mib
from noc.core.snmp.render import render_bin
class Script(BaseScript):
...
def execute_snmp(self, **kwargs):
...
for oid, ports_mask in self.snmp.getnext(
mib["Q-BRIDGE-MIB::dot1qVlanCurrentEgressPorts"],
display_hints={mib["Q-BRIDGE-MIB::dot1qVlanCurrentEgressPorts"]: render_bin},
):
...
The HTTP module in NOC allows you to perform GET and POST requests to interact with network devices using HTTP. To make HTTP requests, you provide a URL as an argument, and the module returns the response. If an error occurs during the HTTP request, it raises an HTTPError exception (noc.core.script.http.base.HTTPError).
::: noc.core.script.http.base:HTTP.get selection: docstring_style: restructured-text rendering: show_root_heading: true heading_level: 4 show_category_heading: true
::: noc.core.script.http.base:HTTP.post selection: docstring_style: restructured-text rendering: show_root_heading: true heading_level: 4 show_category_heading: true
When making an HTTP request, you have the option to use the "Basic" authentication scheme by setting the use_basic
parameter to True
. More complex authentication schemes are implemented using the "Middleware" mechanism. Middleware is an intermediate handler that receives the request before it's sent, allowing you to modify the request data or headers. Built-in handlers can be found in the noc.core.script.http.middleware.*
module, and to apply them, you need to specify their names in the http_request_middleware
setting in the SA profile. To enable Middleware, the following settings are available in the profile:
enable_http_session
: Authenticates once per session.http_request_middleware
: A list of Middleware handlers to apply.
For example, to use "Digest" authentication, you can add digestauth
to your profile.py
:
enable_http_session = True
http_request_middleware = [
"digestauth",
]
If necessary, you can add custom middleware handlers for your profile. These handlers inherit from the BaseMiddleware
class and should be placed in the <profile>/middleware/
folder. To use your custom middleware, add an import statement in the http_request_middleware
setting in the profile:
For example:
# Python modules
import orjson
import hashlib
import codecs
# NOC modules
from noc.core.script.http.middleware.base import BaseMiddleware
from noc.core.http.client import fetch_sync
from noc.core.comp import smart_bytes
class AuthMiddeware(BaseMiddleware):
"""
Append HTTP Digest authorisation headers
"""
name = "customauth"
MML¶
The Machine Messaging Language (MML) protocol is used for machine-to-machine data exchange and is commonly used in various telephony systems, such as Private Branch Exchanges (PBX).
RTSP¶
The Real-Time Streaming Protocol (RTSP) is used for streaming media, particularly in video surveillance systems, including cameras and video recorders, to control the flow of video streams. It also allows for requesting information about available streams. For example, to obtain the status of an RTSP port, you can use the following format:
from noc.core.script.base import BaseScript
from noc.core.script.rtsp.error import RTSPConnectionRefused, RTSPAuthFailed
class Script(BaseScript):
...
def execute(self, **kwargs):
...
try:
check = self.rtsp("DESCRIBE", "/Streaming/Channels/101/")
except RTSPConnectionRefused:
check = 0
Generic Scripts¶
A set of scripts is already implemented in a generic form using SNMP. They are available within the Generic profile located at ` In this case, the functionality of the base script will be sufficient. self.profile .. literalinclude:: ../examples/get_version.py :language: python .. literalinclude:: ../examples/get_capabilities.py :language: python .. _rst-application-label: ::: noc.core.script.base:BaseScript selection: docstring_style: restructured-text members: true filters: - "!_x_seq" - "!call" - "!init" - "!apply_matchers" - "!clean_input" - "!clean_output" - "!run" - "!compile_match_filter" - "!match" - "!call_method" - "!root" - "!get_cache" - "!set_cache" - "!schedule_to_save" - "!push_prompt_pattern" - "!pop_prompt_pattern" - "!get_timeout" - "!get_cli_stream" - "!close_cli_stream" - "!close_snmp" - "!get_mml_stream" - "!close_mml_stream" - "!get_rtsp_stream" - "!close_rtsp_stream" - "!close_current_session" - "!close_session" - "!get_access_preference" - "!get_always_preferred" - "!to_reuse_cli_session" - "!to_keep_cli_session" - "!push_cli_tracking" - "!push_snmp_tracking" - "!iter_cli_fsm_tracking" - "!request_beef" rendering: heading_level: 4 show_source: false show_category_heading: true show_root_toc_entry: false show_if_no_docstring: true .. automodule:: noc.core.script.base :members: :undoc-members: :show-inheritance: .. _rst-interfaces-label: The profile sends data to the main system through a data exchange interface. The interface describes the format and set of data that a script implementing it should return. There are several interfaces available for profile implementation: ::: noc.sa.interfaces.igetversion:IGetVersion rendering: show_source: true ::: noc.sa.interfaces.igetinterfaces:IGetInterfaces selection: docstring_style: restructured-text rendering: show_source: true .. automodule:: noc.sa.interfaces.igetversion :members: .. automodule:: noc.sa.interfaces.igetcapabilities :members: .. automodule:: noc.sa.interfaces.igetinterfaces :members: :show-inheritance: .. automodule:: noc.sa.interfaces.igetchassisid :members: .. automodule:: noc.sa.interfaces.igetfqdn :members: .. automodule:: noc.sa.interfaces.igetlldpneighbors :members: .. automodule:: noc.sa.interfaces.igetcdpneighbors .. automodule:: noc.sa.interfaces.igetarp :members: .. automodule:: noc.sa.interfaces.igetmacaddresstable :members: .. automodule:: noc.sa.interfaces.igetconfig :members: .. automodule:: noc.sa.interfaces.igetinventory :members: .. _rst-interface-data-type-label: In the interfaces, the following data types are applied: .. automodule:: noc.sa.interfaces.base :members:# NOC modules
from noc.sa.profiles.Generic.get_interfaces import Script as BaseScript
from noc.sa.interfaces.igetinterfaces import IGetInterfaces
class Script(BaseScript):
name = "<profile_name>.get_interfaces"
interface = IGetInterfaces
Customization¶
Example Scripts¶
Script Base Class¶
NOC Interfaces¶
.. autoclass:: IGetCDPNeighbors
Interface Data Types¶