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 |