librenms /
librenms
| 1 | #!/usr/bin/env php |
||
| 2 | <?php |
||
| 3 | |||
| 4 | use LibreNMS\Config; |
||
| 5 | use LibreNMS\Modules\Core; |
||
| 6 | use LibreNMS\Util\Debug; |
||
| 7 | |||
| 8 | $init_modules = ['']; |
||
| 9 | require __DIR__ . '/../includes/init.php'; |
||
| 10 | |||
| 11 | $options = getopt('h:o:t:v:d::'); |
||
| 12 | |||
| 13 | if ($options['h'] && $options['o'] && $options['t'] && $options['v']) { |
||
| 14 | $type = $options['t']; |
||
| 15 | $vendor = $options['v']; |
||
| 16 | Debug::set(isset($options['d'])); |
||
| 17 | |||
| 18 | $device_id = ctype_digit($options['h']) ? $options['h'] : getidbyname($options['h']); |
||
| 19 | $device = device_by_id_cache($device_id); |
||
| 20 | $definition_file = Config::get('install_dir') . "/includes/definitions/{$options['o']}.yaml"; |
||
| 21 | $discovery_file = Config::get('install_dir') . "/includes/definitions/discovery/{$options['o']}.yaml"; |
||
| 22 | $test_file = Config::get('install_dir') . "/tests/snmpsim/{$options['o']}.snmprec"; |
||
| 23 | if (file_exists($definition_file)) { |
||
| 24 | c_echo("The OS {$options['o']} appears to exist already, skipping to sensors support\n"); |
||
| 25 | } else { |
||
| 26 | $sysDescr = snmp_get($device, 'sysDescr.0', '-OvQ', 'SNMPv2-MIB'); |
||
| 27 | $sysObjectID = explode('.', ltrim(snmp_get($device, 'sysObjectID.0', '-OnvQ', 'SNMPv2-MIB'), '.')); |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 28 | $end_oid = array_pop($sysObjectID); |
||
| 29 | $sysObjectID = '.' . implode('.', $sysObjectID); |
||
| 30 | $full_sysObjectID = "$sysObjectID.$end_oid"; |
||
| 31 | |||
| 32 | c_echo(" |
||
| 33 | sysDescr: $sysDescr |
||
| 34 | sysObjectID: $full_sysObjectID |
||
| 35 | |||
| 36 | "); |
||
| 37 | |||
| 38 | $os = Core::detectOS($device); |
||
| 39 | $continue = 'n'; |
||
| 40 | if ($os != 'generic') { |
||
| 41 | $continue = get_user_input("We already detect this device as OS $os type, do you want to continue to add sensors? (Y/n)"); |
||
| 42 | } |
||
| 43 | |||
| 44 | if (! str_i_contains($continue, 'y')) { |
||
| 45 | $descr = get_user_input('Enter the description for this OS, i.e Cisco IOS:'); |
||
| 46 | $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:'); |
||
| 47 | |||
| 48 | if (filter_var($icon, FILTER_VALIDATE_URL)) { |
||
| 49 | $icon_data = file_get_contents($icon); |
||
| 50 | file_put_contents(Config::get('temp_dir') . "/{$options['o']}", $icon_data); |
||
| 51 | $file_info = mime_content_type(Config::get('temp_dir') . "/{$options['o']}"); |
||
| 52 | if ($file_info === 'image/png') { |
||
| 53 | $ext = '.png'; |
||
| 54 | } elseif ($file_info === 'image/svg+xml') { |
||
| 55 | $ext = '.svg'; |
||
| 56 | } |
||
| 57 | rename(Config::get('temp_dir') . "/{$options['o']}", Config::get('install_dir') . "/html/images/os/$vendor$ext"); |
||
| 58 | $icon = $vendor; |
||
| 59 | } |
||
| 60 | |||
| 61 | $disco = "os: {$options['o']} |
||
| 62 | text: '$descr' |
||
| 63 | type: $type |
||
| 64 | icon: $icon |
||
| 65 | group: $vendor |
||
| 66 | over: |
||
| 67 | - { graph: device_bits, text: 'Device Traffic' } |
||
| 68 | - { graph: device_processor, text: 'CPU Usage' } |
||
| 69 | - { graph: device_mempool, text: 'Memory Usage' } |
||
| 70 | discovery: |
||
| 71 | - sysObjectID: |
||
| 72 | - $sysObjectID |
||
| 73 | "; |
||
| 74 | file_put_contents($definition_file, $disco); |
||
| 75 | |||
| 76 | $snmprec = "1.3.6.1.2.1.1.1.0|4|$sysDescr |
||
| 77 | 1.3.6.1.2.1.1.2.0|6|$full_sysObjectID |
||
| 78 | "; |
||
| 79 | |||
| 80 | file_put_contents($test_file, $snmprec); |
||
| 81 | } |
||
| 82 | |||
| 83 | if ($os === 'generic') { |
||
| 84 | c_echo('Base discovery file created,'); |
||
| 85 | } |
||
| 86 | } |
||
| 87 | |||
| 88 | $mib_name = get_user_input('ctrl+c to exit now otherwise please enter the MIB name including path (url is also fine) for us to check for sensors:'); |
||
| 89 | |||
| 90 | if (filter_var($mib_name, FILTER_VALIDATE_URL)) { |
||
| 91 | $mib_data = file_get_contents($mib_name); |
||
| 92 | file_put_contents(Config::get('temp_dir') . "/{$options['o']}.mib", $mib_data); |
||
| 93 | $file_info = mime_content_type(Config::get('temp_dir') . "/{$options['o']}.mib"); |
||
| 94 | if ($file_info !== 'text/plain') { |
||
| 95 | c_echo("That mib file isn't a plain text file and is instead $file_info so we aren't using it"); |
||
| 96 | exit(1); |
||
| 97 | } |
||
| 98 | preg_match('/(.* DEFINITIONS ::)/', $mib_data, $matches); |
||
| 99 | [$mib_name,] = explode(' ', $matches[0], 2); |
||
| 100 | if (file_exists(Config::get('install_dir') . "/mibs/$vendor/") == false) { |
||
|
0 ignored issues
–
show
|
|||
| 101 | mkdir(Config::get('install_dir') . "/mibs/$vendor/"); |
||
| 102 | } |
||
| 103 | rename(Config::get('temp_dir') . "/{$options['o']}.mib", Config::get('install_dir') . "/mibs/$vendor/$mib_name"); |
||
| 104 | } elseif ($mib_name) { |
||
| 105 | $tmp_mib = explode('/', $mib_name); |
||
| 106 | $mib_name = array_pop($tmp_mib); |
||
| 107 | } |
||
| 108 | |||
| 109 | $translate_cmd = Config::get('snmptranslate') . ' -M ' . Config::get('mib_dir') . ':' . Config::get('mib_dir') . "/$vendor -m $mib_name -TB '.*Table$' -Os"; |
||
| 110 | $tables = shell_exec($translate_cmd); |
||
| 111 | foreach (explode(PHP_EOL, $tables) as $table_name) { |
||
| 112 | if ($table_name) { |
||
| 113 | $continue = get_user_input("Do you want to add $table_name? (y/N)"); |
||
| 114 | if ($continue === 'y' || $continue === 'Y') { |
||
| 115 | $mib2c_cmd = 'env MIBDIRS=' . Config::get('mib_dir') . ':' . Config::get('mib_dir') . "/$vendor/ env MIBS=\"$mib_name\" mib2c -q -c misc/mib2c.conf $table_name"; |
||
| 116 | $tmp_info = shell_exec($mib2c_cmd); |
||
| 117 | $table_info = Symfony\Component\Yaml\Yaml::parse($tmp_info); |
||
| 118 | $type = get_user_input('Enter the sensor type, i.e temperature, voltage, etc:'); |
||
| 119 | echo 'Table info:' . PHP_EOL; |
||
| 120 | foreach ($table_info['data'] as $data) { |
||
| 121 | echo $data['name'] . PHP_EOL; |
||
| 122 | $tmp_table[$data['name']] = $data['oid']; |
||
| 123 | } |
||
| 124 | $value = get_user_input('Enter value:'); |
||
| 125 | $descr = get_user_input('Enter descr:'); |
||
| 126 | $divisor = get_user_input('Enter divisor (defaults to 1)'); |
||
| 127 | $multiplier = get_user_input('Enter multiplier (defaults to 1)'); |
||
| 128 | if ($type && $value && $descr) { |
||
| 129 | $discovery[$type] .= " |
||
| 130 | - |
||
| 131 | oid: $table_name |
||
| 132 | value: $value |
||
| 133 | num_oid: '{$tmp_table[$value]}.{{ \$index }}' |
||
| 134 | descr: $descr"; |
||
| 135 | if ($multiplier) { |
||
| 136 | $discovery[$type] .= "\n multiplier: $multiplier"; |
||
| 137 | } |
||
| 138 | if ($divisor) { |
||
| 139 | $discovery[$type] .= "\n divisor: $divisor"; |
||
| 140 | } |
||
| 141 | } |
||
| 142 | } |
||
| 143 | } |
||
| 144 | } |
||
| 145 | |||
| 146 | if (is_array($discovery)) { |
||
| 147 | $discovery_data = "mib: $mib_name |
||
| 148 | modules: |
||
| 149 | sensors:"; |
||
| 150 | foreach ($discovery as $sensor => $sensor_data) { |
||
| 151 | $discovery_data .= " |
||
| 152 | $sensor: |
||
| 153 | data:$sensor_data"; |
||
| 154 | } |
||
| 155 | } |
||
| 156 | |||
| 157 | if (file_exists($discovery_file) === false) { |
||
| 158 | if (file_put_contents($discovery_file, $discovery_data)) { |
||
| 159 | c_echo("New discovery file $discovery_file has been created"); |
||
| 160 | } else { |
||
| 161 | c_echo("Failed to create new discovery file $discovery_file"); |
||
| 162 | } |
||
| 163 | } else { |
||
| 164 | c_echo("$discovery_file already exists, here's the data we would have added:"); |
||
| 165 | c_echo($discovery_data); |
||
| 166 | } |
||
| 167 | } else { |
||
| 168 | c_echo(' |
||
| 169 | Info: |
||
| 170 | You can use to build the yaml files for a new OS. |
||
| 171 | Usage: |
||
| 172 | -h Is the device ID or hostname of the device in LibreNMS detected as generic |
||
| 173 | -o This is the OS name, i.e ios, nxos, eos |
||
| 174 | -t This is the OS type, i.e network, power, etc |
||
| 175 | -v The vendor name in lower case, i.e cisco, arista |
||
| 176 | |||
| 177 | Example: |
||
| 178 | ./scripts/new-os.php -h 44 -o new-eos |
||
| 179 | |||
| 180 | '); |
||
| 181 | exit(1); |
||
| 182 | } |
||
| 183 | |||
| 184 | function get_user_input($msg) |
||
| 185 | { |
||
| 186 | c_echo($msg . ' '); |
||
| 187 | $handle = fopen('php://stdin', 'r'); |
||
| 188 | $line = fgets($handle); |
||
| 189 | |||
| 190 | return trim($line); |
||
| 191 | } |
||
| 192 |