feature: Added script to generate config for new OS (#7161)

* feature: Added script to generate config for new OS

* scrut fixes
This commit is contained in:
Neil Lathwood 2017-09-04 21:38:09 +01:00 committed by GitHub
parent da0dcda409
commit edae33507a
4 changed files with 200 additions and 0 deletions

View File

@ -10,3 +10,14 @@ During all of these examples we will be using the OS of `pulse` as the example O
> - [Adding Wireless Sensor information.](os/Wireless-Sensors.md)
> - [Adding custom graphs.](os/Custom-Graphs.md)
> - [Adding Unit tests (required).](os/Test-Units.md)
We currently have a script in pre-beta stages that can help speed up the process of deploying a new OS.
It has support for add sensors in a basic form (except state sensors).
In this example, we will add a new OS called test-os using the device ID 101 that has already been added.
It will be of the type network and belongs to the vendor, Cisco:
`./scripts/new-os.php -h 101 -o test-os -t network -v cisco`
The process will then step you through the process with some more questions. Please be warned, this is
currently pre-beta and may cause some issues. Please let us know of any on IRC.

View File

@ -51,6 +51,7 @@ $config['fping_options']['millisec'] = 200;
$config['snmpwalk'] = '/usr/bin/snmpwalk';
$config['snmpget'] = '/usr/bin/snmpget';
$config['snmpbulkwalk'] = '/usr/bin/snmpbulkwalk';
$config['snmptranslate'] = '/usr/bin/snmptranslate';
$config['whois'] = '/usr/bin/whois';
$config['ping'] = '/bin/ping';
$config['mtr'] = '/usr/bin/mtr';

7
misc/mib2c.conf Normal file
View File

@ -0,0 +1,7 @@
@open -@
data:
@foreach $t table@
@foreach $c column@
- { name: $c, oid: $c.objectID }
@end@
@end@

181
scripts/new-os.php Executable file
View File

@ -0,0 +1,181 @@
#!/usr/bin/env php
<?php
$init_modules = array('');
require __DIR__ . '/../includes/init.php';
$options = getopt('h:o:t:v:d::');
if ($options['h'] && $options['o'] && $options['t'] && $options['v']) {
$type = $options['t'];
$vendor = $options['v'];
if (isset($options['d'])) {
$debug = true;
$vdebug = true;
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('log_errors', 1);
ini_set('error_reporting', 1);
}
$device_id = ctype_digit($options['h']) ? $options['h'] : getidbyname($options['h']);
$device = device_by_id_cache($device_id);
$definition_file = $config['install_dir'] . "/includes/definitions/{$options['o']}.yaml";
$discovery_file = $config['install_dir'] . "/includes/definitions/discovery/{$options['o']}.yaml";
$test_file = $config['install_dir'] . "/tests/snmpsim/{$options['o']}.snmprec";
if (file_exists($definition_file)) {
c_echo("The OS {$options['o']} appears to exist already, skipping to sensors support\n");
} else {
$sysDescr = snmp_get($device, 'sysDescr.0', '-OvQ', 'SNMPv2-MIB');
$sysObjectId = explode('.', ltrim(snmp_get($device, 'sysObjectID.0', '-OnvQ', 'SNMPv2-MIB'), '.'));
$end_oid = array_pop($sysObjectId);
$sysObjectId = '.' . implode('.', $sysObjectId);
$full_sysObjectId = "$sysObjectId.$end_oid";
c_echo("
sysDescr: $sysDescr
sysObjectID: $full_sysObjectId
");
$os = getHostOS($device);
if ($os != 'generic') {
c_echo("We already detect this device as OS $os type");
exit(1);
}
$descr = get_user_input('Enter the description for this OS, i.e Cisco IOS:');
$icon = get_user_input('Enter the logo to use, this can be the name of an existing one (i.e: cisco) or the url to retrieve one:');
if (filter_var($icon, FILTER_VALIDATE_URL)) {
$icon_data = file_get_contents($icon);
file_put_contents($config['temp_dir'] . "/{$options['o']}", $icon_data);
$file_info = mime_content_type($config['temp_dir'] . "/{$options['o']}");
if ($file_info === 'image/png') {
$ext = '.png';
} elseif ($file_info === 'image/svg+xml') {
$ext = '.svg';
}
rename($config['temp_dir'] . "/{$options['o']}", $config['install_dir'] . "/html/images/os/$vendor$ext");
$icon = $vendor;
}
$disco = "os: {$options['o']}
text: '$descr'
type: $type
icon: $icon
group: $vendor
over:
- { graph: device_bits, text: 'Device Traffic' }
- { graph: device_processor, text: 'CPU Usage' }
- { graph: device_mempool, text: 'Memory Usage' }
discovery:
- sysObjectId:
- $sysObjectId
";
file_put_contents($definition_file, $disco);
$snmprec = "1.3.6.1.2.1.1.1.0|4|$sysDescr
1.3.6.1.2.1.1.2.0|6|$full_sysObjectId
";
file_put_contents($test_file, $snmprec);
}
$mib_name = get_user_input("Base discovery file created, ctrl+c to exit now otherwise please enter the MIB name including path (url is also fine) for us to check for sensors:");
if (filter_var($mib_name, FILTER_VALIDATE_URL)) {
$mib_data = file_get_contents($mib_name);
file_put_contents($config['temp_dir'] . "/{$options['o']}.mib", $mib_data);
$file_info = mime_content_type($config['temp_dir'] . "/{$options['o']}.mib");
if ($file_info !== 'text/plain') {
c_echo("That mib file isn't a plain text file and is instead $file_info so we aren't using it");
exit(1);
}
preg_match('/(.* DEFINITIONS ::)/', $mib_data, $matches);
list($mib_name,) = explode(' ', $matches[0], 2);
if (file_exists($config['install_dir'] . "/mibs/$vendor/") == false) {
mkdir($config['install_dir'] . "/mibs/$vendor/");
}
rename($config['temp_dir'] . "/{$options['o']}.mib", $config['install_dir'] . "/mibs/$vendor/$mib_name");
}
$tables = `{$config['snmptranslate']} -M {$config['mib_dir']}:{$config['mib_dir']}/$vendor -m $mib_name -TB '.*Table$' -Os`;
foreach (explode(PHP_EOL, $tables) as $table_name) {
if ($table_name) {
$continue = get_user_input("Do you want to add $table_name? (y/N)");
if ($continue === 'y' || $continue === 'Y') {
$tmp_info = `env MIBDIRS={$config['mib_dir']}:{$config['mib_dir']}/$vendor/ env MIBS="$mib_name" mib2c -q -c misc/mib2c.conf $table_name`;
$table_info = Symfony\Component\Yaml\Yaml::parse($tmp_info);
$type = get_user_input('Enter the sensor type, i.e temperature, voltage, etc:');
echo 'Table info:' . PHP_EOL;
foreach ($table_info['data'] as $data) {
echo $data['name'] . PHP_EOL;
$tmp_table[$data['name']] = $data['oid'];
}
$value = get_user_input('Enter value:');
$descr = get_user_input('Enter descr:');
$divisor = get_user_input('Enter divisor (defaults to 1)');
$multiplier = get_user_input('Enter multiplier (defaults to 1)');
if ($type && $value && $descr) {
$discovery[$type] .= "
-
oid: $table_name
value: $value,
num_oid: {$tmp_table[$value]}.
descr: $descr";
if ($multiplier) {
$discovery[$type] .= "\n multiplier: $multiplier";
}
if ($divisor) {
$discovery[$type] .= "\n divisor: $divisor";
}
}
}
}
}
if (is_array($discovery)) {
$discovery_data = "mib: $mib_name
modules:
sensors:";
foreach ($discovery as $sensor => $sensor_data) {
$discovery_data .= "
$sensor:
data:$sensor_data";
}
}
if (file_exists($discovery_file) === false) {
if (file_put_contents($discovery_file, $discovery_data)) {
c_echo("New discovery file $discovery_file has been created");
} else {
c_echo("Failed to create new discovery file $discovery_file");
}
} else {
c_echo("$discovery_file already exists, here's the data we would have added:");
c_echo($discovery_data);
}
} else {
c_echo("
Info:
You can use to build the yaml files for a new OS.
Usage:
-h Is the device ID or hostname of the device in LibreNMS detected as generic
-o This is the OS name, i.e ios, nxos, eos
-t This is the OS type, i.e network, power, etc
-v The vendor name in lower case, i.e cisco, arista
Example:
./scripts/new-os.php -h 44 -o new-eos
");
exit(1);
}
function get_user_input($msg)
{
c_echo($msg . ' ');
$handle = fopen("php://stdin", "r");
$line = fgets($handle);
return trim($line);
}