Files
librenms-librenms/LibreNMS/Modules/OS.php
Tony Murray b573c9ef73 Implement OS specific information discovery (#11446)
* Implement OS specific information discovery
That way it doesn't have to be fetched during polling
Also improve discovery process, os is only detected once, in the core module.
EXA is the test os, a couple improvements there.

* Use local variable, then unset it so we don't pollute.

* fix style issues

* test and other fixes

* attribute update fixes

* Update exa data, need new source data

* null missing "os" values

* fix ftos odd character

* fix ftos odd character

* only null for new style or we will reset to null every discovery

* Move device observer to own class

* Handle location, relocate event logging

* update exa e7-2 data

* update ird test data, apparently unicode is now working.

* update Linux ntc, now uses correct icon

* Only load all os on the web, also, we can't load existing the the database isn't connected.

* only for devices that have a location

* revert ftos test data apparently

* revert ird
2020-05-14 11:27:59 -05:00

117 lines
4.0 KiB
PHP

<?php
/**
* OS.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2020 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Modules;
use LibreNMS\Config;
use LibreNMS\Interfaces\Discovery\OSDiscovery;
use LibreNMS\Interfaces\Module;
use LibreNMS\Interfaces\Polling\OSPolling;
use LibreNMS\Util\Url;
class OS implements Module
{
public function discover(\LibreNMS\OS $os)
{
if ($os instanceof OSDiscovery) {
// null out values in case they aren't filled.
$os->getDeviceModel()->fill([
'hardware' => null,
'version' => null,
'features' => null,
'serial' => null,
'icon' => null,
// 'location_id' => null, // TODO set location
]);
$os->discoverOS();
}
$this->handleChanges($os);
}
public function poll(\LibreNMS\OS $os)
{
$deviceModel = $os->getDeviceModel();
if ($os instanceof OSPolling) {
$os->pollOS();
} else {
// legacy poller files
$device = $os->getDevice();
if (is_file(base_path('/includes/polling/os/' . $device['os'] . '.inc.php'))) {
// OS Specific
include base_path('/includes/polling/os/' . $device['os'] . '.inc.php');
} elseif ($device['os_group'] && base_path('/includes/polling/os/' . $device['os_group'] . '.inc.php')) {
// OS Group Specific
include base_path('/includes/polling/os/' . $device['os_group'] . '.inc.php');
} else {
echo "Generic :(\n";
}
// handle legacy variables, sometimes they are false
$deviceModel->version = ($version ?? $deviceModel->version) ?: null;
$deviceModel->hardware = ($hardware ?? $deviceModel->hardware) ?: null;
$deviceModel->features = ($features ?? $deviceModel->features) ?: null;
$deviceModel->serial = ($serial ?? $deviceModel->serial) ?: null;
}
$this->updateLocation($os, $location ?? null);
$this->handleChanges($os);
}
public function cleanup(\LibreNMS\OS $os)
{
// no cleanup needed?
}
private function handleChanges(\LibreNMS\OS $os)
{
$device = $os->getDeviceModel();
$device->icon = basename(Url::findOsImage($device->os, $device->features, null, 'images/os/'));
echo trans("device.attributes.location") . ": $device->location\n";
foreach (['hardware', 'version', 'features', 'serial'] as $attribute) {
echo \App\Observers\DeviceObserver::attributeChangedMessage($attribute, $device->$attribute, $device->getOriginal($attribute)) . PHP_EOL;
}
$device->save();
}
private function updateLocation(\LibreNMS\OS $os, $altLocation = null)
{
$device = $os->getDeviceModel();
if ($device->override_sysLocation == 0) {
$device->setLocation($altLocation ?? snmp_get($os->getDevice(), 'sysLocation.0', '-Ovq', 'SNMPv2-MIB'));
}
// make sure the location has coordinates
if (Config::get('geoloc.latlng', true) && $device->location && !$device->location->hasCoordinates()) {
$device->location->lookupCoordinates();
$device->location->save();
}
}
}