source: Developing/Support-New-OS.md This document will explain how to add basic and full support for a new OS. **Some knowledge in PHP is needed for the full support.** #### BASIC SUPPORT FOR A NEW OS ### MIB If we have the MIB, we can copy the file into the default directory: ```bash /opt/librenms/mibs ``` #### New OS definition Let's begin to declare the new OS in LibreNMS. At first we create a new definition file located here: ```bash includes/definitions/$os.yaml ``` This is a [Yaml file](https://en.wikipedia.org/wiki/YAML). Please be careful of the formatting of this file. ```yaml os: pulse text: 'Pulse Secure' type: firewall icon: pulse over: - { graph: device_bits, text: 'Device Traffic' } - { graph: device_processor, text: 'CPU Usage' } - { graph: device_mempool, text: 'Memory Usage' } discovery: - sysDescr: - Pulse Connect Secure - Pulse Secure - Juniper Networks,Inc,VA-DTE - VA-SPE ``` #### Icon and Logo Create an SVG image of the icon and logo. Legacy PNG bitmaps are also supported but look bad on HiDPI. - A vector image should not contain padding. - The file should not be larger than 20 Kb. Simplify paths to reduce large files. - Use plain SVG without gzip compression. ##### Icon - Save the icon SVG to **html/images/os/$os.svg**. - Icons should look good when viewed at 32x32 px. - Square icons are preferred to full logos with text. - Remove small ornaments that are almost not visible when displayed with 32px width (e.g. ® or ™). ##### Logo - Save the logo SVG to **html/images/logos/$os.svg**. - Logos can be any dimension, but often are wide and contain the company name. - If a logo is not present, the icon will be used. ##### Hints Hints for [Inkscape](https://inkscape.org/): - You can open a PDF to extract the logo. - Ungroup elements to isolate the logo. - Use `Path -> Simplify` to simplify paths of large files. - Use `File -> Document Properties… -> Resize page to content…` to remove padding. - Use `File -> Clean up document` to remove unused gradients, patterns, or markers. - Use `File -> Save As -> Plain SVG` to save the final image. By optimizing the SVG you can shrink the file size in some cases to less than 20 %. [SVG Optimizer](https://github.com/svg/svgo) does a great job. There is also an [online version](https://jakearchibald.github.io/svgomg/). #### OS Discovery The discovery section of the OS yaml file contains information needed to detect this OS. ##### Discovery Operators - `sysObjectId` The preferred operator. Checks if the sysObjectID starts with one of the strings under this item - `sysDescr` Use this in addition to sysObjectId if required. Check that the sysDescr contains one of the strings under this item - `sysDescr_regex` Please avoid use of this. Checks if the sysDescr matches one of the regex statements under this item ##### Discoery Logic YAML is converted to an array in PHP. Consider the following YAML: ```yaml discovery: - sysObjectId: foo - sysDescr: [ snafu, exodar ] sysObjectId: bar ``` This is how the discovery array would look in PHP: ```php [ [ "sysObjectId" => "foo", ], [ "sysDescr" => [ "snafu", "exodar", ], "sysObjectId" => "bar", ] ] ``` The logic for the discovery is as follows: 1. One of the first level items must match 2. ALL of the second level items must match (sysObjectId, sysDescr) 3. One of the third level items (foo, [snafu,exodar], bar) must match So, considering the example: - `sysObjectId: foo, sysDescr: ANYTHING` matches - `sysObjectId: bar, sysDescr: ANYTHING` does not match - `sysObjectId: bar, sysDescr: exodar` matches - `sysObjectId: bar, sysDescr: snafu` matches #### Basic OS information polling Here is the file location for polling the new OS within a vendor MIB or a standard one: ```bash includes/polling/os/pulse.inc.php ``` This file will usually set the variables for $version, $hardware and $hostname retrieved from an snmp lookup. ```php $users, ); $tags = compact('rrd_def'); data_update($device, 'pulse_users', $tags, $fields); $graphs['pulse_users'] = true; } $sessions = snmp_get($device, 'iveConcurrentUsers.0', '-OQv', 'PULSESECURE-PSG-MIB'); if (is_numeric($sessions)) { $rrd_def = 'DS:sessions:GAUGE:600:0:U'; $fields = array( 'sessions' => $sessions, ); $tags = compact('rrd_def'); data_update($device, 'pulse_sessions', $tags, $fields); $graphs['pulse_sessions'] = true; } ``` We finish in the declaration of the two graph types in the database: We can do that within a file to share our work and contribute in the development of LibreNMS. :-) ```bash sql-schema/xxx.sql //check the file number in GitHub php includes/sql-schema/update.php ``` Or put the SQL commands directly in Mysql or PhpMyadmin for our tests: ```php INSERT INTO `graph_types`(`graph_type`, `graph_subtype`, `graph_section`, `graph_descr`, `graph_order`) VALUES ('device', 'pulse_users', 'firewall', 'Active Users', ''); INSERT INTO `graph_types`(`graph_type`, `graph_subtype`, `graph_section`, `graph_descr`, `graph_order`) VALUES ('device', 'pulse_sessions', 'firewall', 'Active Sessions', ''); ``` #### Displaying The specific graphs are not displayed automatically so we need to write the following PHP code: **Pulse Sessions** ```bash html/includes/graphs/device/pulse_sessions.inc.php ``` ```php checkOS('nios'); $this->checkOS('nios', 'nios-ipam'); } ``` We utilise [snmpsim](http://snmpsim.sourceforge.net/) to do unit testing for OS discovery. For this to work you need to supply an snmprec file. This is pretty simple and using nios as the example again this would look like: ``` 1.3.6.1.2.1.1.1.0|4|Linux 3.14.25 #1 SMP Thu Jun 16 18:19:37 EDT 2016 x86_64 1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.7779.1.1402 ``` During testing LibreNMS will use any info in the snmprec file for snmp calls. This one provides sysDescr (`.1.3.6.1.2.1.1.1.0`, 4 = Octet String) and sysObjectID (`.1.3.6.1.2.1.1.2.0`, 6 = Object Identifier), which is the minimum that should be provided for new snmprec files. To look up the numeric OID and type of an string OID with snmptranslate: ```bash snmptranslate -On -Td SNMPv2-MIB::sysDescr.0 ``` Common OIDs used in discovery: | String OID | Numeric OID | | ----------------------------------- | --------------------------- | | SNMPv2-MIB::sysDescr.0 | 1.3.6.1.2.1.1.1.0 | | SNMPv2-MIB::sysObjectID.0 | 1.3.6.1.2.1.1.2.0 | | ENTITY-MIB::entPhysicalDescr.1 | 1.3.6.1.2.1.47.1.1.1.1.2.1 | | ENTITY-MIB::entPhysicalMfgName.1 | 1.3.6.1.2.1.47.1.1.1.1.12.1 | | SML-MIB::product-Name.0 | 1.3.6.1.4.1.2.6.182.3.3.1.0 | List of SNMP data types: | Type | Value | | ----------------- | ------------- | | OCTET STRING | 4 | | HEX STRING | 4x | | Integer32 | 2 | | NULL | 5 | | OBJECT IDENTIFIER | 6 | | IpAddress | 64 | | Counter32 | 65 | | Gauge32 | 66 | | TimeTicks | 67 | | Opaque | 68 | | Counter64 | 70 | Hex encoded strings (4x) should be used for any strings that contain line returns You can run `./scripts/pre-commit.php -u` to run the unit tests to check your code. If you would like to run tests locally against a full snmpsim instance, run `./scripts/pre-commit.php -u --snmpsim`.