Configurable device display name (#13528)

* Configurable device display name
You can just set the display name in device settings.

It also accepts simple template format with  the variables: hostname, sysName, sysName_fallback, ip

Default controlled by device_display_default, (set from old force_hostname_to_sysname and force_ip_to_sysname settings

* remove second argument to format_hostname()

* Style fixes

* Update schema

* update phpstan baseline

* Improved settings strings (and add for translation)
This commit is contained in:
Tony Murray
2021-11-18 15:46:22 -06:00
committed by GitHub
parent 69d0753ec4
commit 790c4b3402
24 changed files with 196 additions and 159 deletions

View File

@@ -446,6 +446,18 @@ class Config
self::deprecatedVariable('poller_modules.cisco-sla', 'poller_modules.slas');
self::deprecatedVariable('oxidized.group', 'oxidized.maps.group');
// migrate device display
if (! self::has('device_display_default')) {
$display_value = '{{ $hostname }}';
if (self::get('force_hostname_to_sysname')) {
$display_value = '{{ $sysName }}';
} elseif (self::get('force_ip_to_sysname')) {
$display_value = '{{ $sysName_fallback }}';
}
self::persist('device_display_default', $display_value);
}
$persist = Eloquent::isConnected();
// make sure we have full path to binaries in case PATH isn't set
foreach (['fping', 'fping6', 'snmpgetnext', 'rrdtool', 'traceroute', 'traceroute6'] as $bin) {

View File

@@ -2,6 +2,7 @@
namespace App\Models;
use App\View\SimpleTemplate;
use Fico7489\Laravel\Pivot\Traits\PivotEventTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -47,6 +48,7 @@ class Device extends BaseModel
'features',
'hardware',
'hostname',
'display',
'icon',
'ip',
'os',
@@ -163,27 +165,32 @@ class Device extends BaseModel
}
/**
* Get the display name of this device (hostname) unless force_ip_to_sysname is set
* and hostname is an IP and sysName is set
*
* @return string
* Get the display name of this device based on the display format string
* The default is {{ $hostname }} controlled by the device_display_default setting
*/
public function displayName()
public function displayName(): string
{
if (\LibreNMS\Config::get('force_ip_to_sysname') && $this->sysName && IP::isValid($this->hostname)) {
return $this->sysName;
}
$hostname_is_ip = IP::isValid($this->hostname);
return $this->hostname;
return SimpleTemplate::parse($this->display ?: \LibreNMS\Config::get('device_display_default', '{{ $hostname }}'), [
'hostname' => $this->hostname,
'sysName' => $this->sysName ?: $this->hostname,
'sysName_fallback' => $hostname_is_ip ? $this->sysName : $this->hostname,
'ip' => $this->overwrite_ip ?: ($hostname_is_ip ? $this->hostname : $this->ip),
]);
}
public function name()
/**
* Returns the device name if not already displayed
*/
public function name(): string
{
$displayName = $this->displayName();
if ($this->sysName !== $displayName) {
return $this->sysName;
} elseif ($this->hostname !== $displayName && $this->hostname !== $this->ip) {
$display = $this->displayName();
if (! Str::contains($display, $this->hostname)) {
return $this->hostname;
} elseif (! Str::contains($display, $this->sysName)) {
return $this->sysName;
}
return '';

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class DeviceAddDisplayField extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('devices', function (Blueprint $table) {
$table->string('display', 128)->nullable()->after('sysName');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('devices', function (Blueprint $table) {
$table->dropColumn(['display']);
});
}
}

View File

@@ -5,11 +5,11 @@
"/css/app.css": "/css/app.css?id=4f966be7eb5693f68d0e",
"/js/vendor.js": "/js/vendor.js?id=b90d598798a7357bce8f",
"/js/lang/de.js": "/js/lang/de.js?id=1aedfce25e3daad3046a",
"/js/lang/en.js": "/js/lang/en.js?id=53887c60e27dd28dbcfc",
"/js/lang/en.js": "/js/lang/en.js?id=18d18b0b43c83bf56010",
"/js/lang/fr.js": "/js/lang/fr.js?id=a20c4c78eb5f9f4a374b",
"/js/lang/it.js": "/js/lang/it.js?id=4e3b200da489000822dd",
"/js/lang/it.js": "/js/lang/it.js?id=6b0bdf3be6dc3bf0a167",
"/js/lang/ru.js": "/js/lang/ru.js?id=f6b7c078755312a0907c",
"/js/lang/uk.js": "/js/lang/uk.js?id=1bba323982918f74fa33",
"/js/lang/zh-CN.js": "/js/lang/zh-CN.js?id=b4219bb8e090803ee079",
"/js/lang/zh-TW.js": "/js/lang/zh-TW.js?id=64b924a4a9a744aaf020"
"/js/lang/zh-TW.js": "/js/lang/zh-TW.js?id=7495f99f35742c3e06b5"
}

View File

@@ -652,28 +652,20 @@ function inet6_ntop($ip)
* If hostname is an ip, use return sysName
*
* @param array $device (uses hostname and sysName fields)
* @param string $hostname
* @return string
*/
function format_hostname($device, $hostname = null)
function format_hostname($device): string
{
if (empty($hostname)) {
$hostname = $device['hostname'];
}
$hostname = $device['hostname'] ?? 'invalid hostname';
$hostname_is_ip = IP::isValid($hostname);
$sysName = empty($device['sysName']) ? $hostname : $device['sysName'];
if (Config::get('force_hostname_to_sysname') && ! empty($device['sysName'])) {
if (\LibreNMS\Util\Validate::hostname($hostname) && ! IP::isValid($hostname)) {
return $device['sysName'];
}
}
if (Config::get('force_ip_to_sysname') && ! empty($device['sysName'])) {
if (IP::isValid($hostname)) {
return $device['sysName'];
}
}
return $hostname;
return \App\View\SimpleTemplate::parse(empty($device['display']) ? Config::get('device_display_default', '{{ $hostname }}') : $device['display'], [
'hostname' => $hostname,
'sysName' => $sysName,
'sysName_fallback' => $hostname_is_ip ? $sysName : $hostname,
'ip' => empty($device['overwrite_ip']) ? ($hostname_is_ip ? $device['hostname'] : $device['ip'] ?? '') : $device['overwrite_ip'],
]);
}
/**

View File

@@ -42,10 +42,12 @@ if (! empty($device['overwrite_ip'])) {
echo "<div class='row'><div class='col-sm-4'>Assigned IP</div><div class='col-sm-8'>{$device['overwrite_ip']}</div></div>";
} elseif (! empty($device['ip'])) {
echo "<div class='row'><div class='col-sm-4'>Resolved IP</div><div class='col-sm-8'>{$device['ip']}</div></div>";
} elseif (Config::get('force_ip_to_sysname') === true) {
} else {
try {
$ip = IP::parse($device['hostname']);
echo "<div class='row'><div class='col-sm-4'>IP Address</div><div class='col-sm-8'>$ip</div></div>";
$ip = (string) IP::parse($device['hostname']);
if ($ip !== format_hostname($device)) {
echo "<div class='row'><div class='col-sm-4'>IP Address</div><div class='col-sm-8'>$ip</div></div>";
}
} catch (InvalidIpException $e) {
// don't add an ip line
}

View File

@@ -8,8 +8,8 @@ foreach (explode(',', $vars['id']) as $ifid) {
if (Rrd::checkRrdExists($rrd_file)) {
$port = cleanPort($port);
$rrd_list[$i]['filename'] = $rrd_file;
$rrd_list[$i]['descr'] = format_hostname($port, $port['hostname']) . ' ' . $port['ifDescr'];
$rrd_list[$i]['descr_in'] = format_hostname($port, $port['hostname']);
$rrd_list[$i]['descr'] = format_hostname($port) . ' ' . $port['ifDescr'];
$rrd_list[$i]['descr_in'] = format_hostname($port);
$rrd_list[$i]['descr_out'] = makeshortif($port['label']);
$i++;
}

View File

@@ -8,6 +8,7 @@ $device_model = Device::find($device['device_id']);
if ($_POST['editing']) {
if (Auth::user()->hasGlobalAdmin()) {
$reload = false;
if (isset($_POST['parent_id'])) {
$parents = array_diff((array) $_POST['parent_id'], ['0']);
// TODO avoid loops!
@@ -27,6 +28,7 @@ if ($_POST['editing']) {
}
$device_model->override_sysLocation = $override_sysLocation;
$device_model->display = empty($_POST['display']) ? null : $_POST['display'];
$device_model->purpose = $_POST['descr'];
$device_model->poller_group = $_POST['poller_group'];
$device_model->ignore = (int) isset($_POST['ignore']);
@@ -39,6 +41,10 @@ if ($_POST['editing']) {
set_dev_attrib($device, 'override_device_type', true);
}
if ($device_model->isDirty('display')) {
$reload = true;
}
if ($device_model->isDirty()) {
if ($device_model->save()) {
flash()->addSuccess(__('Device record updated'));
@@ -49,15 +55,10 @@ if ($_POST['editing']) {
if (isset($_POST['hostname']) && $_POST['hostname'] !== '' && $_POST['hostname'] !== $device['hostname']) {
if (Auth::user()->hasGlobalAdmin()) {
$result = renamehost($device['device_id'], $_POST['hostname'], 'webui');
$result = renamehost($device['device_id'], trim($_POST['hostname']), 'webui');
if ($result == '') {
flash()->addSuccess("Hostname updated from {$device['hostname']} to {$_POST['hostname']}");
echo '
<script>
var loc = window.location;
window.location.replace(loc.protocol + "//" + loc.host + loc.pathname + loc.search);
</script>
';
$reload = true;
} else {
flash()->addError($result . '. Does your web server have permission to modify the rrd files?');
}
@@ -80,6 +81,11 @@ if ($_POST['editing']) {
if (isset($override_sysContact_string)) {
set_dev_attrib($device, 'override_sysContact_string', $override_sysContact_string);
}
// some changed data not stateful, just reload the page
if ($reload) {
echo '<script>window.location.reload();</script>';
}
} else {
include 'includes/html/error-no-perm.inc.php';
}
@@ -119,18 +125,24 @@ $disable_notify = get_dev_attrib($device, 'disable_notify');
<?php echo csrf_field() ?>
<input type=hidden name="editing" value="yes">
<div class="form-group" data-toggle="tooltip" data-container="body" data-placement="bottom" title="Change the hostname used for name resolution" >
<label for="edit-hostname-input" class="col-sm-2 control-label" >Hostname:</label>
<label for="edit-hostname-input" class="col-sm-2 control-label" >Hostname / IP:</label>
<div class="col-sm-6">
<input type="text" id="edit-hostname-input" name="hostname" class="form-control" disabled value=<?php echo \LibreNMS\Util\Clean::html($device['hostname'], []); ?> />
<input type="text" id="edit-hostname-input" name="hostname" class="form-control" disabled value="<?php echo htmlentities($device['hostname']); ?>" />
</div>
<div class="col-sm-2">
<button name="hostname-edit-button" id="hostname-edit-button" class="btn btn-danger"> <i class="fa fa-pencil"></i> </button>
<button type="button" name="hostname-edit-button" id="hostname-edit-button" class="btn btn-danger" onclick="toggleHostnameEdit()"> <i class="fa fa-pencil"></i> </button>
</div>
</div>
<div class="form-group" data-toggle="tooltip" data-container="body" data-placement="bottom" title="Display Name for this device. Keep short. Available placeholders: hostname, sysName, sysName_fallback, ip" >
<label for="edit-display-input" class="col-sm-2 control-label" >Display Name:</label>
<div class="col-sm-6">
<input type="text" id="edit-display-input" name="display" class="form-control" placeholder="System Default" value="<?php echo htmlentities($device_model->display); ?>">
</div>
</div>
<div class="form-group" data-toggle="tooltip" data-container="body" data-placement="bottom" title="Use this IP instead of resolved one for polling" >
<label for="edit-overwrite_ip-input" class="col-sm-2 control-label" >Overwrite IP:</label>
<label for="edit-overwrite_ip-input" class="col-sm-2 control-label text-danger" >Overwrite IP (do not use):</label>
<div class="col-sm-6">
<input type="text" id="edit-overwrite_up-input" name="overwrite_ip" class="form-control" value=<?php echo $device_model->overwrite_ip; ?>>
<input type="text" id="edit-overwrite_ip-input" name="overwrite_ip" class="form-control" value="<?php echo htmlentities($device_model->overwrite_ip); ?>">
</div>
</div>
<div class="form-group">
@@ -185,7 +197,7 @@ $disable_notify = get_dev_attrib($device, 'disable_notify');
if (! $device_model->override_sysLocation) {
echo ' disabled="1"';
}
?> value="<?php echo \LibreNMS\Util\Clean::html($device_model->location, []); ?>" />
?> value="<?php echo htmlentities($device_model->location); ?>" />
</div>
</div>
<div class="form-group">
@@ -210,7 +222,7 @@ $disable_notify = get_dev_attrib($device, 'disable_notify');
echo ' disabled="1"';
}
?>
value="<?php echo $override_sysContact_string; ?>" />
value="<?php echo htmlentities($override_sysContact_string); ?>" />
</div>
</div>
<div class="form-group">
@@ -354,21 +366,9 @@ If `devices.ignore = 0` or `macros.device = 1` condition is is set and ignore al
}
});
});
$('#hostname-edit-button').on("click", function(e) {
e.preventDefault();
disabled_state = document.getElementById('edit-hostname-input').disabled;
if (disabled_state == true) {
document.getElementById('edit-hostname-input').disabled = false;
} else {
document.getElementById('edit-hostname-input').disabled = true;
}
});
$('#sysLocation').on('keypress', function (e) {
if(e.keyCode === 13) {
e.preventDefault();
$('#edit').trigger( "submit" );
}
});
function toggleHostnameEdit() {
document.getElementById('edit-hostname-input').disabled = ! document.getElementById('edit-hostname-input').disabled;
}
$('#parent_id').select2({
width: 'resolve'
});

View File

@@ -113,7 +113,7 @@ if (! Auth::user()->hasGlobalAdmin()) {
}
if (! $done) {
echo "<option value='" . $device['device_id'] . "'>" . format_hostname($device, $device['hostname']) . '</option>';
echo "<option value='" . $device['device_id'] . "'>" . format_hostname($device) . '</option>';
}
}
@@ -233,7 +233,7 @@ if (! Auth::user()->hasGlobalAdmin()) {
}
if (! $done) {
echo "<option value='" . $device['device_id'] . "'>" . format_hostname($device, $device['hostname']) . '</option>';
echo "<option value='" . $device['device_id'] . "'>" . format_hostname($device) . '</option>';
}
}

View File

@@ -64,7 +64,7 @@ foreach (dbFetchRows('SELECT * FROM `devices` ORDER BY `hostname`') as $data) {
echo '" selected"+';
}
echo '">' . format_hostname($data, $data['hostname']) . '</option>"+';
echo '">' . format_hostname($data) . '</option>"+';
}
}
?>

View File

@@ -30,7 +30,7 @@ $pagetitle[] = 'Oxidized';
<tr>
<th data-column-id="id" data-visible="false">ID</th>
<th data-column-id="hostname" data-formatter="hostname" data-order="asc">Hostname</th>
<th data-column-id="sysname" data-visible=" <?php echo ! Config::get('force_ip_to_sysname') ? 'true' : 'false' ?>">SysName</th>
<th data-column-id="sysname" data-visible="false">SysName</th>
<th data-column-id="last_status" data-formatter="status">Last Status</th>
<th data-column-id="last_update">Last Update</th>
<th data-column-id="model">Model</th>

View File

@@ -40,7 +40,7 @@ var grid = $("#fdb-search").bootgrid({
<?php
// Select the devices only with FDB tables
$sql = 'SELECT D.device_id AS device_id, `hostname` FROM `ports_fdb` AS F, `ports` AS P, `devices` AS D';
$sql = 'SELECT D.device_id AS device_id, `hostname`, `sysName`, `display` FROM `ports_fdb` AS F, `ports` AS P, `devices` AS D';
$param = [];
if (! Auth::user()->hasGlobalRead()) {
@@ -56,7 +56,7 @@ foreach (dbFetchRows($sql, $param) as $data) {
echo '" selected "+';
}
echo '">' . format_hostname($data, $data['hostname']) . '</option>"+';
echo '">' . format_hostname($data) . '</option>"+';
}
?>
"</select>"+

View File

@@ -29,7 +29,7 @@ var grid = $("#ipv4-search").bootgrid({
"<option value=\"\">All Devices</option>"+
<?php
$sql = 'SELECT `devices`.`device_id`,`hostname`,`sysName` FROM `devices`';
$sql = 'SELECT `devices`.`device_id`,`hostname`,`sysName`,`display` FROM `devices`';
$param = [];
if (! Auth::user()->hasGlobalRead()) {
@@ -46,7 +46,7 @@ foreach (dbFetchRows($sql, $param) as $data) {
echo '" selected "+';
}
echo '">' . format_hostname($data, $data['hostname']) . '</option>"+';
echo '">' . format_hostname($data) . '</option>"+';
}
?>
"</select>"+

View File

@@ -28,7 +28,7 @@ var grid = $("#ipv6-search").bootgrid({
"<option value=\"\">All Devices</option>"+
<?php
$sql = 'SELECT `devices`.`device_id`,`hostname`, `sysName` FROM `devices`';
$sql = 'SELECT `devices`.`device_id`,`hostname`, `sysName`, `display` FROM `devices`';
$param = [];
if (! Auth::user()->hasGlobalRead()) {
@@ -45,7 +45,7 @@ foreach (dbFetchRows($sql, $param) as $data) {
echo '" selected"+';
}
echo '">' . format_hostname($data, $data['hostname']) . '</option>"+';
echo '">' . format_hostname($data) . '</option>"+';
}
?>
"</select>"+

View File

@@ -62,12 +62,14 @@ if (in_array('mac', Config::get('network_map_items'))) {
`D1`.`os` AS `local_os`,
`D1`.`hostname` AS `local_hostname`,
`D1`.`sysName` AS `local_sysName`,
`D1`.`display` AS `local_display`,
`D2`.`status` AS `remote_status`,
`D2`.`device_id` AS `remote_device_id`,
`D2`.`disabled` AS `remote_disabled`,
`D2`.`os` AS `remote_os`,
`D2`.`hostname` AS `remote_hostname`,
`D2`.`sysName` AS `remote_sysName`,
`D2`.`display` AS `remote_display`,
`P1`.`port_id` AS `local_port_id`,
`P1`.`device_id` AS `local_port_device_id`,
`P1`.`ifName` AS `local_ifname`,
@@ -111,12 +113,14 @@ if (in_array('xdp', Config::get('network_map_items'))) {
`D1`.`disabled` AS `local_disabled`,
`D1`.`hostname` AS `local_hostname`,
`D1`.`sysName` AS `local_sysName`,
`D1`.`display` AS `local_display`,
`D2`.`status` AS `remote_status`,
`D2`.`device_id` AS `remote_device_id`,
`D2`.`disabled` AS `remote_disabled`,
`D2`.`os` AS `remote_os`,
`D2`.`hostname` AS `remote_hostname`,
`D2`.`sysName` AS `remote_sysName`,
`D2`.`display` AS `remote_display`,
`P1`.`port_id` AS `local_port_id`,
`P1`.`device_id` AS `local_port_device_id`,
`P1`.`ifName` AS `local_ifname`,
@@ -206,11 +210,15 @@ foreach ($list as $items) {
'device_id'=>$items['local_device_id'],
'os'=>$items['local_os'],
'hostname'=>$items['local_hostname'],
'sysName' => $items['local_sysName'],
'display' => $items['local_display'],
];
$remote_device = [
'device_id'=>$items['remote_device_id'],
'os'=>$items['remote_os'],
'hostname'=>$items['remote_hostname'],
'sysName' => $items['remote_sysName'],
'display' => $items['remote_display'],
];
$local_port = [
'port_id'=>$items['local_port_id'],
@@ -231,10 +239,9 @@ foreach ($list as $items) {
$local_device_id = $items['local_device_id'];
if (! array_key_exists($local_device_id, $devices_by_id)) {
$items['sysName'] = $items['local_sysName'];
$devices_by_id[$local_device_id] = [
'id'=>$local_device_id,
'label'=>shorthost(format_hostname($items, $items['local_hostname']), 1),
'label'=>shorthost(format_hostname($local_device), 1),
'title'=>generate_device_link($local_device, '', [], '', '', '', 0),
'shape'=>'box',
];
@@ -251,8 +258,7 @@ foreach ($list as $items) {
$remote_device_id = $items['remote_device_id'];
if (! array_key_exists($remote_device_id, $devices_by_id)) {
$items['sysName'] = $items['remote_sysName'];
$devices_by_id[$remote_device_id] = ['id'=>$remote_device_id, 'label'=>shorthost(format_hostname($items, $items['remote_hostname']), 1), 'title'=>generate_device_link($remote_device, '', [], '', '', '', 0), 'shape'=>'box'];
$devices_by_id[$remote_device_id] = ['id'=>$remote_device_id, 'label'=>shorthost(format_hostname($remote_device), 1), 'title'=>generate_device_link($remote_device, '', [], '', '', '', 0), 'shape'=>'box'];
if ($items['remote_disabled'] != '0') {
$devices_by_id[$remote_device_id] = array_merge($devices_by_id[$remote_device_id], $node_disabled_style);
} elseif ($items['remote_status'] == '0') {

View File

@@ -172,7 +172,7 @@ foreach ($ports as $port) {
$port['out_rate'] = \LibreNMS\Util\Number::formatSi(($port['ifOutOctets_rate'] * 8), 2, 3, 'bps');
$port = cleanPort($port, $device);
$csv[] = [
format_hostname($port, $port['hostname']),
format_hostname($port),
\LibreNMS\Util\Rewrite::normalizeIfName($port['label']),
$speed,
$port['in_rate'],

View File

@@ -108,7 +108,7 @@ if ($rowCount != -1) {
$sql .= " LIMIT $limit_low,$limit_high";
}
$sql = "SELECT `alerts`.*, `devices`.`hostname`, `devices`.`sysName`, `devices`.`os`, `devices`.`hardware`, `locations`.`location`, `alert_rules`.`rule`, `alert_rules`.`name`, `alert_rules`.`severity` $sql";
$sql = "SELECT `alerts`.*, `devices`.`hostname`, `devices`.`sysName`, `devices`.`display`, `devices`.`os`, `devices`.`hardware`, `locations`.`location`, `alert_rules`.`rule`, `alert_rules`.`name`, `alert_rules`.`severity` $sql";
$rulei = 0;
$format = $vars['format'];
@@ -140,7 +140,7 @@ foreach (dbFetchRows($sql, $param) as $alert) {
}
}
$hostname = '<div class="incident">' . generate_device_link($alert, format_hostname($alert, shorthost($alert['hostname']))) . '<div id="incident' . ($alert['id']) . '"';
$hostname = '<div class="incident">' . generate_device_link($alert, shorthost(format_hostname($alert))) . '<div id="incident' . ($alert['id']) . '"';
if (is_numeric($vars['uncollapse_key_count'])) {
$hostname .= $max_row_length < (int) $vars['uncollapse_key_count'] ? '' : ' class="collapse"';
} else {

View File

@@ -874,6 +874,19 @@
"ifAlias": "ifAlias"
}
},
"device_display_default": {
"group": "webui",
"section": "device",
"order": 1,
"default": null,
"type": "select",
"options": {
"{{ $hostname }}": "hostname",
"{{ $sysName_fallback }}": "sysName_fallback",
"{{ $sysName }}": "sysName",
"{{ $ip }}": "ip"
}
},
"device_perf_purge": {
"default": 7,
"units": "days",
@@ -1597,20 +1610,6 @@
"order": 2,
"type": "text"
},
"force_hostname_to_sysname": {
"group": "webui",
"section": "device",
"order": 0,
"default": false,
"type": "boolean"
},
"force_ip_to_sysname": {
"group": "webui",
"section": "device",
"order": 1,
"default": false,
"type": "boolean"
},
"fping": {
"default": "fping",
"group": "external",

View File

@@ -495,6 +495,7 @@ devices:
- { Field: inserted, Type: timestamp, 'Null': true, Extra: '', Default: CURRENT_TIMESTAMP }
- { Field: hostname, Type: varchar(128), 'Null': false, Extra: '' }
- { Field: sysName, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: display, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: ip, Type: varbinary(16), 'Null': true, Extra: '' }
- { Field: overwrite_ip, Type: varchar(40), 'Null': true, Extra: '' }
- { Field: community, Type: varchar(255), 'Null': true, Extra: '' }

View File

@@ -9255,11 +9255,6 @@ parameters:
count: 1
path: app/Models/Device.php
-
message: "#^Method App\\\\Models\\\\Device\\:\\:name\\(\\) has no return type specified\\.$#"
count: 1
path: app/Models/Device.php
-
message: "#^Method App\\\\Models\\\\Device\\:\\:scopeHasAccess\\(\\) has no return type specified\\.$#"
count: 1

View File

@@ -1436,18 +1436,20 @@ return [
'help' => 'Minimum Graph Height (default: 300)',
],
],
'device_display_default' => [
'description' => 'Default device display name template',
'help' => 'Sets the default display name for all devices (can be overridden per-device). Hostname/IP: Just show the hostname or IP the device was added with. sysName: Just show the sysName from snmp. Hostname or sysName: Show hostname, but if it is an IP, show sysName.',
'options' => [
'hostname' => 'Hostname / IP',
'sysName_fallback' => 'Hostname, fallback to sysName for IPs',
'sysName' => 'sysName',
'ip' => 'IP (from hostname IP or resolved)',
],
],
'device_location_map_open' => [
'description' => 'Location Map open',
'help' => 'Location Map is shown by default',
],
'force_hostname_to_sysname' => [
'description' => 'show SysName instead of Hostname',
'help' => 'When using a dynamic DNS hostname or one that does not resolve, this option would allow you to make use of the sysName instead as the preferred reference to the device',
],
'force_ip_to_sysname' => [
'description' => 'show SysName instead of IP Address',
'help' => 'When using IP addresses as a hostname you can instead represent the devices on the WebUI by its sysName resulting in an easier to read overview of your network. This would apply on networks where you don\'t have DNS records for most of your devices',
],
'whois' => [
'description' => 'Path to whois',
],

View File

@@ -1248,14 +1248,6 @@ return [
'description' => 'Location Map open',
'help' => 'Location Map is shown by default',
],
'force_hostname_to_sysname' => [
'description' => 'use SNMP SysName instead of Hostname',
'help' => 'When using a dynamic DNS hostname or one that does not resolve, this option would allow you to make use of the SNMP sysName instead as the preferred reference to the device',
],
'force_ip_to_sysname' => [
'description' => 'use SNMP SysName instead of IP Address',
'help' => 'When using IP addresses as a hostname you can instead represent the devices on the WebUI by its SNMP sysName resulting in an easier to read overview of your network. This would apply on networks where you don\'t have DNS records for most of your devices',
],
'whois' => [
'description' => 'Path to whois',
],

View File

@@ -980,14 +980,6 @@ return [
'description' => '開啟位置圖',
'help' => 'Location Map is shown by default',
],
'force_hostname_to_sysname' => [
'description' => '將 Hostname 改以 SysName 顯示',
'help' => 'When using a dynamic DNS hostname or one that does not resolve, this option would allow you to make use of the sysName instead as the preferred reference to the device',
],
'force_ip_to_sysname' => [
'description' => '將 IP 位址改以 SysName 顯示',
'help' => 'When using IP addresses as a hostname you can instead represent the devices on the WebUI by its sysName resulting in an easier to read overview of your network. This would apply on networks where you don\'t have DNS records for most of your devices',
],
'whois' => [
'description' => 'whois 路徑',
],

View File

@@ -172,50 +172,55 @@ class CommonFunctionsTest extends TestCase
'hostname' => 'test.librenms.org',
'sysName' => 'Testing DNS',
];
$invalid_dns = [
'hostname' => 'Not DNS',
'sysName' => 'Testing Invalid DNS',
];
$device_ip = [
'hostname' => '192.168.1.2',
'sysName' => 'Testing IP',
];
$invalid_ip = [
'hostname' => '256.168.1.2',
'sysName' => 'Testing Invalid IP',
];
$custom_display = [
'hostname' => 'test.librenms.org',
'sysName' => 'sysName',
'display' => 'Custom Display ({{ $hostname }} {{ $sysName }})',
];
// both false
Config::set('force_ip_to_sysname', false);
Config::set('force_hostname_to_sysname', false);
// default {{ $hostname }}
Config::set('device_display_default', null);
$this->assertEquals('test.librenms.org', format_hostname($device_dns));
$this->assertEquals('Not DNS', format_hostname($device_dns, 'Not DNS'));
$this->assertEquals('192.168.5.5', format_hostname($device_dns, '192.168.5.5'));
$this->assertEquals('Not DNS', format_hostname($invalid_dns));
$this->assertEquals('192.168.1.2', format_hostname($device_ip));
$this->assertEquals('hostname.like', format_hostname($device_ip, 'hostname.like'));
$this->assertEquals('10.10.10.10', format_hostname($device_ip, '10.10.10.10'));
$this->assertEquals('256.168.1.2', format_hostname($invalid_ip));
$this->assertEquals('Custom Display (test.librenms.org sysName)', format_hostname($custom_display));
// ip to sysname
Config::set('force_ip_to_sysname', true);
Config::set('force_hostname_to_sysname', false);
Config::set('device_display_default', '{{ $sysName_fallback }}');
$this->assertEquals('test.librenms.org', format_hostname($device_dns));
$this->assertEquals('Not DNS', format_hostname($device_dns, 'Not DNS'));
$this->assertEquals('Testing DNS', format_hostname($device_dns, '192.168.5.5'));
$this->assertEquals('Not DNS', format_hostname($invalid_dns));
$this->assertEquals('Testing IP', format_hostname($device_ip));
$this->assertEquals('hostname.like', format_hostname($device_ip, 'hostname.like'));
$this->assertEquals('Testing IP', format_hostname($device_ip, '10.10.10.10'));
$this->assertEquals('256.168.1.2', format_hostname($invalid_ip));
$this->assertEquals('Custom Display (test.librenms.org sysName)', format_hostname($custom_display));
// dns to sysname
Config::set('force_ip_to_sysname', false);
Config::set('force_hostname_to_sysname', true);
// sysname
Config::set('device_display_default', '{{ $sysName }}');
$this->assertEquals('Testing DNS', format_hostname($device_dns));
$this->assertEquals('Not DNS', format_hostname($device_dns, 'Not DNS'));
$this->assertEquals('192.168.5.5', format_hostname($device_dns, '192.168.5.5'));
$this->assertEquals('192.168.1.2', format_hostname($device_ip));
$this->assertEquals('Testing IP', format_hostname($device_ip, 'hostname.like'));
$this->assertEquals('10.10.10.10', format_hostname($device_ip, '10.10.10.10'));
// both true
Config::set('force_ip_to_sysname', true);
Config::set('force_hostname_to_sysname', true);
$this->assertEquals('Testing DNS', format_hostname($device_dns));
$this->assertEquals('Not DNS', format_hostname($device_dns, 'Not DNS'));
$this->assertEquals('Testing DNS', format_hostname($device_dns, '192.168.5.5'));
$this->assertEquals('Testing Invalid DNS', format_hostname($invalid_dns));
$this->assertEquals('Testing IP', format_hostname($device_ip));
$this->assertEquals('Testing IP', format_hostname($device_ip, 'hostname.like'));
$this->assertEquals('Testing IP', format_hostname($device_ip, '10.10.10.10'));
$this->assertEquals('Testing Invalid IP', format_hostname($invalid_ip));
$this->assertEquals('Custom Display (test.librenms.org sysName)', format_hostname($custom_display));
// custom
$custom_ip = ['display' => 'IP: {{ $ip }}', 'hostname' => '1.1.1.1', 'ip' => '2.2.2.2'];
$this->assertEquals('IP: 1.1.1.1', format_hostname($custom_ip));
$custom_ip['hostname'] = 'not_ip';
$this->assertEquals('IP: 2.2.2.2', format_hostname($custom_ip));
$custom_ip['overwrite_ip'] = '3.3.3.3';
$this->assertEquals('IP: 3.3.3.3', format_hostname($custom_ip));
}
public function testPortAssociation()