Issues (2963)

scripts/new-os.php (1 issue)

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'), '.'));
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
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
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