mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Offer opt in to usage and error reporting during install (#13906)
and on the about page
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
namespace LibreNMS;
|
namespace LibreNMS;
|
||||||
|
|
||||||
|
use App\Models\Callback;
|
||||||
use App\Models\GraphType;
|
use App\Models\GraphType;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
@@ -472,6 +473,9 @@ class Config
|
|||||||
if (! self::has('snmp.unescape')) {
|
if (! self::has('snmp.unescape')) {
|
||||||
self::persist('snmp.unescape', version_compare(Version::get()->netSnmp(), '5.8.0', '<'));
|
self::persist('snmp.unescape', version_compare(Version::get()->netSnmp(), '5.8.0', '<'));
|
||||||
}
|
}
|
||||||
|
if (! self::has('reporting.usage')) {
|
||||||
|
self::persist('reporting.usage', (bool) Callback::get('enabled'));
|
||||||
|
}
|
||||||
|
|
||||||
self::populateTime();
|
self::populateTime();
|
||||||
|
|
||||||
|
@@ -50,6 +50,7 @@ use App\Models\Syslog;
|
|||||||
use App\Models\Vlan;
|
use App\Models\Vlan;
|
||||||
use App\Models\Vrf;
|
use App\Models\Vrf;
|
||||||
use App\Models\WirelessSensor;
|
use App\Models\WirelessSensor;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use LibreNMS\Config;
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Data\Store\Rrd;
|
use LibreNMS\Data\Store\Rrd;
|
||||||
@@ -59,12 +60,12 @@ class AboutController extends Controller
|
|||||||
{
|
{
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$callback_status = Callback::get('enabled') === '1';
|
|
||||||
$version = Version::get();
|
$version = Version::get();
|
||||||
|
|
||||||
return view('about.index', [
|
return view('about.index', [
|
||||||
'callback_status' => $callback_status,
|
'usage_reporting_status' => Config::get('reporting.usage'),
|
||||||
'callback_uuid' => $callback_status ? Callback::get('uuid') : null,
|
'error_reporting_status' => Config::get('reporting.error'),
|
||||||
|
'reporting_clearable' => Callback::whereIn('name', ['uuid', 'error_reporting_uuid'])->exists(),
|
||||||
|
|
||||||
'db_schema' => $version->database(),
|
'db_schema' => $version->database(),
|
||||||
'git_log' => $version->git->log(),
|
'git_log' => $version->git->log(),
|
||||||
@@ -105,4 +106,21 @@ class AboutController extends Controller
|
|||||||
'stat_wireless' => WirelessSensor::count(),
|
'stat_wireless' => WirelessSensor::count(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function clearReportingData(): JsonResponse
|
||||||
|
{
|
||||||
|
$usage_uuid = Callback::get('uuid');
|
||||||
|
|
||||||
|
// try to clear usage data if we have a uuid
|
||||||
|
if ($usage_uuid) {
|
||||||
|
if (! \Http::post(Config::get('callback_clear'), ['uuid' => $usage_uuid])->successful()) {
|
||||||
|
return response()->json([], 500); // don't clear if this fails to delete upstream data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear all reporting ids
|
||||||
|
Callback::truncate();
|
||||||
|
|
||||||
|
return response()->json();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,9 +26,12 @@
|
|||||||
namespace App\Http\Controllers\Install;
|
namespace App\Http\Controllers\Install;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use LibreNMS\Config;
|
||||||
use LibreNMS\Exceptions\FileWriteFailedException;
|
use LibreNMS\Exceptions\FileWriteFailedException;
|
||||||
use LibreNMS\Interfaces\InstallerStep;
|
use LibreNMS\Interfaces\InstallerStep;
|
||||||
use LibreNMS\Util\EnvHelper;
|
use LibreNMS\Util\EnvHelper;
|
||||||
|
use LibreNMS\Util\Git;
|
||||||
|
|
||||||
class FinalizeController extends InstallationController implements InstallerStep
|
class FinalizeController extends InstallationController implements InstallerStep
|
||||||
{
|
{
|
||||||
@@ -40,6 +43,29 @@ class FinalizeController extends InstallationController implements InstallerStep
|
|||||||
return $this->redirectToIncomplete();
|
return $this->redirectToIncomplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return view('install.finish', $this->formatData([
|
||||||
|
'can_update' => Git::make()->isAvailable(),
|
||||||
|
'success' => '',
|
||||||
|
'env' => '',
|
||||||
|
'config' => '',
|
||||||
|
'messages' => '',
|
||||||
|
'env_message' => '',
|
||||||
|
'config_message' => '',
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveConfig(Request $request): \Illuminate\Http\JsonResponse
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'update_channel' => 'in:master,release',
|
||||||
|
'site_style' => 'in:light,dark',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->saveSetting('update_channel', $request->get('update_channel', 'master'));
|
||||||
|
$this->saveSetting('site_style', $request->get('site_style'));
|
||||||
|
$this->saveSetting('reporting.error', $request->has('error_reporting'));
|
||||||
|
$this->saveSetting('reporting.usage', $request->has('usage_reporting'));
|
||||||
|
|
||||||
$env = '';
|
$env = '';
|
||||||
$config = '';
|
$config = '';
|
||||||
$config_file = base_path('config.php');
|
$config_file = base_path('config.php');
|
||||||
@@ -65,14 +91,14 @@ class FinalizeController extends InstallationController implements InstallerStep
|
|||||||
$env_message = trans('install.finish.env_not_written');
|
$env_message = trans('install.finish.env_not_written');
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('install.finish', $this->formatData([
|
return response()->json([
|
||||||
'success' => $success,
|
'success' => $success,
|
||||||
'env' => $env,
|
'env' => $env,
|
||||||
'config' => $config,
|
'config' => $config,
|
||||||
'messages' => $messages,
|
'messages' => $messages,
|
||||||
'env_message' => $env_message,
|
'env_message' => $env_message,
|
||||||
'config_message' => $config_message,
|
'config_message' => $config_message,
|
||||||
]));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function writeEnvFile()
|
private function writeEnvFile()
|
||||||
@@ -138,6 +164,18 @@ class FinalizeController extends InstallationController implements InstallerStep
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param mixed $value
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function saveSetting(string $name, $value): void
|
||||||
|
{
|
||||||
|
if (Config::get($name) !== $value) {
|
||||||
|
Config::persist($name, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function enabled(): bool
|
public function enabled(): bool
|
||||||
{
|
{
|
||||||
foreach ($this->hydrateControllers() as $step => $controller) {
|
foreach ($this->hydrateControllers() as $step => $controller) {
|
||||||
|
@@ -60,8 +60,8 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
private function bootCustomBladeDirectives()
|
private function bootCustomBladeDirectives()
|
||||||
{
|
{
|
||||||
Blade::if('config', function ($key) {
|
Blade::if('config', function ($key, $value = true) {
|
||||||
return \LibreNMS\Config::get($key);
|
return \LibreNMS\Config::get($key) == $value;
|
||||||
});
|
});
|
||||||
Blade::if('notconfig', function ($key) {
|
Blade::if('notconfig', function ($key) {
|
||||||
return ! \LibreNMS\Config::get($key);
|
return ! \LibreNMS\Config::get($key);
|
||||||
|
@@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LibreNMS
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
|
||||||
*
|
|
||||||
* 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. Please see LICENSE.txt at the top level of
|
|
||||||
* the source code distribution for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
header('Content-type: text/plain');
|
|
||||||
|
|
||||||
if (! Auth::user()->hasGlobalAdmin()) {
|
|
||||||
exit('ERROR: You need to be admin');
|
|
||||||
}
|
|
||||||
|
|
||||||
\App\Models\Callback::set('enabled', '2');
|
|
@@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LibreNMS
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
|
||||||
*
|
|
||||||
* 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. Please see LICENSE.txt at the top level of
|
|
||||||
* the source code distribution for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
header('Content-type: text/plain');
|
|
||||||
|
|
||||||
if (! Auth::user()->hasGlobalAdmin()) {
|
|
||||||
exit('ERROR: You need to be admin');
|
|
||||||
}
|
|
||||||
|
|
||||||
\App\Models\Callback::set('enabled', (int) ($_POST['state'] == 'true'));
|
|
@@ -4866,6 +4866,16 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"reporting.dump_errors": {
|
"reporting.dump_errors": {
|
||||||
|
"group": "system",
|
||||||
|
"section": "reporting",
|
||||||
|
"order": 1,
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"reporting.usage": {
|
||||||
|
"group": "system",
|
||||||
|
"section": "reporting",
|
||||||
|
"order": 0,
|
||||||
"default": false,
|
"default": false,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
@@ -737,8 +737,8 @@ return [
|
|||||||
'update_channel' => [
|
'update_channel' => [
|
||||||
'description' => 'Definiere Updatekanal',
|
'description' => 'Definiere Updatekanal',
|
||||||
'options' => [
|
'options' => [
|
||||||
'master' => 'master',
|
'master' => 'Daily',
|
||||||
'release' => 'release',
|
'release' => 'Monthly',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'virsh' => [
|
'virsh' => [
|
||||||
|
@@ -28,18 +28,19 @@ return [
|
|||||||
'config_not_written' => 'Could not write config.php',
|
'config_not_written' => 'Could not write config.php',
|
||||||
'config_written' => 'config.php file written',
|
'config_written' => 'config.php file written',
|
||||||
'copied' => 'Copied to clipboard',
|
'copied' => 'Copied to clipboard',
|
||||||
|
'dashboard' => 'Dashboard',
|
||||||
'env_manual' => 'Manually update :file with the following content',
|
'env_manual' => 'Manually update :file with the following content',
|
||||||
'env_not_written' => 'Could not write .env file',
|
'env_not_written' => 'Could not write .env file',
|
||||||
'env_written' => '.env file written',
|
'env_written' => '.env file written',
|
||||||
|
'failed' => 'Failed to save .env',
|
||||||
|
'finish' => 'Finish Install',
|
||||||
'manual_copy' => 'Press Ctrl-C to copy',
|
'manual_copy' => 'Press Ctrl-C to copy',
|
||||||
'not_finished' => 'You have not quite finished yet!',
|
|
||||||
'retry' => 'Retry',
|
'retry' => 'Retry',
|
||||||
'statistics' => 'It would be great if you would consider contributing to our statistics, you can do this on the :about and check the box under Statistics.',
|
'settings' => 'Additional Settings',
|
||||||
'statistics_link' => 'About LibreNMS Page',
|
'success' => 'Install Complete',
|
||||||
'thanks' => 'Thank you for setting up LibreNMS.',
|
'thanks' => 'Thank you for setting up LibreNMS.',
|
||||||
'title' => 'Finish Install',
|
'title' => 'Finish Install',
|
||||||
'validate' => 'First, you need to :validate and fix any issues.',
|
'validate_button' => 'Validate Install',
|
||||||
'validate_link' => 'validate your install',
|
|
||||||
],
|
],
|
||||||
'install' => 'Install',
|
'install' => 'Install',
|
||||||
'migrate' => [
|
'migrate' => [
|
||||||
|
@@ -72,6 +72,7 @@ return [
|
|||||||
'proxy' => ['name' => 'Proxy'],
|
'proxy' => ['name' => 'Proxy'],
|
||||||
'updates' => ['name' => 'Updates'],
|
'updates' => ['name' => 'Updates'],
|
||||||
'server' => ['name' => 'Server'],
|
'server' => ['name' => 'Server'],
|
||||||
|
'reporting' => ['name' => 'Reporting'],
|
||||||
],
|
],
|
||||||
'webui' => [
|
'webui' => [
|
||||||
'availability-map' => ['name' => 'Availability Map Settings'],
|
'availability-map' => ['name' => 'Availability Map Settings'],
|
||||||
@@ -1250,6 +1251,16 @@ return [
|
|||||||
'help' => 'Networks/IPs which will not be discovered automatically. Excludes also IPs from Autodiscovery Networks',
|
'help' => 'Networks/IPs which will not be discovered automatically. Excludes also IPs from Autodiscovery Networks',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'reporting' => [
|
||||||
|
'error' => [
|
||||||
|
'description' => 'Send Error Reports',
|
||||||
|
'help' => 'Sends some errors to LibreNMS for analysis and fixing',
|
||||||
|
],
|
||||||
|
'usage' => [
|
||||||
|
'description' => 'Send Usage Reports',
|
||||||
|
'help' => 'Reports usage and versions to LibreNMS. To delete anonymous stats, visit the about page. You can view stats at https://stats.librenms.org',
|
||||||
|
],
|
||||||
|
],
|
||||||
'route_purge' => [
|
'route_purge' => [
|
||||||
'description' => 'Route entries older than',
|
'description' => 'Route entries older than',
|
||||||
'help' => 'Cleanup done by daily.sh',
|
'help' => 'Cleanup done by daily.sh',
|
||||||
@@ -1381,7 +1392,7 @@ return [
|
|||||||
'help' => 'Shrinks hostname to maximum length, but always complete subdomain parts',
|
'help' => 'Shrinks hostname to maximum length, but always complete subdomain parts',
|
||||||
],
|
],
|
||||||
'site_style' => [
|
'site_style' => [
|
||||||
'description' => 'Set the site css style',
|
'description' => 'Default Theme',
|
||||||
'options' => [
|
'options' => [
|
||||||
'blue' => 'Blue',
|
'blue' => 'Blue',
|
||||||
'dark' => 'Dark',
|
'dark' => 'Dark',
|
||||||
@@ -1511,10 +1522,10 @@ return [
|
|||||||
'description' => 'Enable updates in ./daily.sh',
|
'description' => 'Enable updates in ./daily.sh',
|
||||||
],
|
],
|
||||||
'update_channel' => [
|
'update_channel' => [
|
||||||
'description' => 'Set update Channel',
|
'description' => 'Update Channel',
|
||||||
'options' => [
|
'options' => [
|
||||||
'master' => 'master',
|
'master' => 'Daily',
|
||||||
'release' => 'release',
|
'release' => 'Monthly',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'uptime_warning' => [
|
'uptime_warning' => [
|
||||||
|
@@ -1077,8 +1077,8 @@ return [
|
|||||||
'update_channel' => [
|
'update_channel' => [
|
||||||
'description' => 'Choisir le canal des mises à jour',
|
'description' => 'Choisir le canal des mises à jour',
|
||||||
'options' => [
|
'options' => [
|
||||||
'master' => 'master',
|
'master' => 'Daily',
|
||||||
'release' => 'release',
|
'release' => 'Monthly',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'uptime_warning' => [
|
'uptime_warning' => [
|
||||||
|
@@ -1491,8 +1491,8 @@ return [
|
|||||||
'update_channel' => [
|
'update_channel' => [
|
||||||
'description' => 'Set update Channel',
|
'description' => 'Set update Channel',
|
||||||
'options' => [
|
'options' => [
|
||||||
'master' => 'master',
|
'master' => 'Daily',
|
||||||
'release' => 'release',
|
'release' => 'Monthly',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'uptime_warning' => [
|
'uptime_warning' => [
|
||||||
|
@@ -1482,8 +1482,8 @@ return [
|
|||||||
'update_channel' => [
|
'update_channel' => [
|
||||||
'description' => 'Визначити канал оновлень',
|
'description' => 'Визначити канал оновлень',
|
||||||
'options' => [
|
'options' => [
|
||||||
'master' => 'master',
|
'master' => 'Daily',
|
||||||
'release' => 'release',
|
'release' => 'Monthly',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'uptime_warning' => [
|
'uptime_warning' => [
|
||||||
|
@@ -752,8 +752,8 @@ return [
|
|||||||
'update_channel' => [
|
'update_channel' => [
|
||||||
'description' => '设定更新频道',
|
'description' => '设定更新频道',
|
||||||
'options' => [
|
'options' => [
|
||||||
'master' => 'master',
|
'master' => 'Daily',
|
||||||
'release' => 'release',
|
'release' => 'Monthly',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'virsh' => [
|
'virsh' => [
|
||||||
|
@@ -925,8 +925,8 @@ return [
|
|||||||
'update_channel' => [
|
'update_channel' => [
|
||||||
'description' => '設定更新頻道',
|
'description' => '設定更新頻道',
|
||||||
'options' => [
|
'options' => [
|
||||||
'master' => 'master',
|
'master' => 'Daily',
|
||||||
'release' => 'release',
|
'release' => 'Monthly',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'uptime_warning' => [
|
'uptime_warning' => [
|
||||||
|
@@ -90,29 +90,29 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
||||||
<h3>{{ __('Statistics') }}</h3>
|
<h3>{{ __('Reporting & Statistics') }}</h3>
|
||||||
|
|
||||||
<table class='table table-condensed'>
|
<table class='table table-condensed'>
|
||||||
|
|
||||||
@admin
|
@admin
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan='4'>
|
<td colspan='4'>
|
||||||
<span class='bg-danger'>
|
<div>
|
||||||
<label for="callback">{{ __('Opt in to send anonymous usage statistics to LibreNMS?') }}</label><br />
|
<label for="reporting.usage" class="bg-info">{{ __('Opt in to send anonymous reports to LibreNMS?') }}</label>
|
||||||
</span>
|
</div>
|
||||||
<input type="checkbox" id="callback" data-size="normal" name="statistics" @if($callback_status) checked @endif>
|
<div>
|
||||||
<br />
|
{{ __('Error reporting:') }} <input type="checkbox" id="reporting.error" name="reporting" data-size="small" @if($error_reporting_status) checked @endif>
|
||||||
{{ __('Online stats:') }} <a target="_blank" href='https://stats.librenms.org/'>stats.librenms.org</a>
|
</div>
|
||||||
|
<div class="tw-mt-2">
|
||||||
|
{{ __('Usage statistics:') }} <input type="checkbox" id="reporting.usage" name="reporting" data-size="small" @if($usage_reporting_status) checked @endif> <a target="_blank" href='https://stats.librenms.org/'>stats.librenms.org</a>
|
||||||
|
</div>
|
||||||
|
@if($reporting_clearable)
|
||||||
|
<div class="tw-mt-2">
|
||||||
|
<button class='btn btn-danger btn-xs' type='submit' name='clear-reporting' id='clear-reporting'>{{ __('Clear reporting data') }}</button>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@isset($callback_uuid)
|
|
||||||
<tr>
|
|
||||||
<td colspan='4'>
|
|
||||||
<button class='btn btn-danger btn-xs' type='submit' name='clear-stats' id='clear-stats'>{{ __('Clear remote stats') }}</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endisset
|
|
||||||
@endadmin
|
@endadmin
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
@@ -202,29 +202,29 @@ along with this program. If not, see <a target="_blank" href="https://www.gnu.o
|
|||||||
|
|
||||||
@section('scripts')
|
@section('scripts')
|
||||||
<script>
|
<script>
|
||||||
$("[name='statistics']").bootstrapSwitch('offColor','danger','size','mini');
|
$("[name='reporting']").bootstrapSwitch('offColor','danger','size','mini');
|
||||||
$('input[name="statistics"]').on('switchChange.bootstrapSwitch', function(event, state) {
|
$('input[name="reporting"]').on('switchChange.bootstrapSwitch', function(event, state) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
const type = event.target.id;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'PUT',
|
||||||
url: 'ajax_form.php',
|
url: '{{ route('settings.update', '?') }}'.replace('?', type),
|
||||||
data: { type: "callback-statistics", state: state},
|
data: JSON.stringify({value: state}),
|
||||||
dataType: "json",
|
contentType: "application/json",
|
||||||
success: function(data){},
|
success: function(data){},
|
||||||
error:function(){
|
error:function(){
|
||||||
return $("#switch-state").bootstrapSwitch("toggle");
|
return $("#" + type).bootstrapSwitch("toggle");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('#clear-stats').on("click", function(event) {
|
$('#clear-reporting').on("click", function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'DELETE',
|
||||||
url: 'ajax_form.php',
|
url: '{{ route('reporting.clear') }}',
|
||||||
data: { type: "callback-clear"},
|
success: function(){
|
||||||
dataType: "json",
|
$('#clear-reporting').remove();
|
||||||
success: function(data){
|
$("#callback").bootstrapSwitch('state', false);
|
||||||
location.reload(true);
|
|
||||||
},
|
},
|
||||||
error:function(){}
|
error:function(){}
|
||||||
});
|
});
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
{{ __('install.database.credentials') }}
|
{{ __('install.database.credentials') }}
|
||||||
<span class="fa-pull-right"><i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed"></i></span>
|
<span class="float-right"><i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="db-form-container" class="card-body collapse @if(!$valid_credentials) show @endif">
|
<div id="db-form-container" class="card-body collapse @if(!$valid_credentials) show @endif">
|
||||||
<form id="database-form" class="form-horizontal" role="form" method="post" action="{{ route('install.acton.test-database') }}">
|
<form id="database-form" class="form-horizontal" role="form" method="post" action="{{ route('install.acton.test-database') }}">
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
{{ __('install.migrate.migrate') }}
|
{{ __('install.migrate.migrate') }}
|
||||||
<span class="fa-pull-right"><i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed"></i></span>
|
<span class="float-right"><i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="migrate-container" class="card-body collapse @if(!$migrated) show @endif">
|
<div id="migrate-container" class="card-body collapse @if(!$migrated) show @endif">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@@ -1,104 +1,206 @@
|
|||||||
@extends('layouts.install')
|
@extends('layouts.install')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="card mb-2">
|
<div class="card mb-2">
|
||||||
<div class="card-header h6" data-toggle="collapse" data-target="#env-file-text" aria-expanded="{{ $success ? 'false' : 'true' }}">
|
<div class="card-header h6">
|
||||||
@if($success)
|
{{ __('install.finish.settings') }}
|
||||||
<i class="fa-solid fa-lg fa-square-check text-success"></i>
|
|
||||||
@else
|
|
||||||
<i class="fa-solid fa-lg fa-rectangle-xmark text-danger"></i>
|
|
||||||
@endif
|
|
||||||
{{ $env_message }}
|
|
||||||
@if($env)<i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed pull-right"></i>@endif($env)
|
|
||||||
</div>
|
|
||||||
@if($env)
|
|
||||||
<div id="env-file-text" class="card-body collapse @if(!$success) show @endif">
|
|
||||||
<button class="btn btn-primary float-right" onclick="location.reload()">{{ __('install.finish.retry') }}</button>
|
|
||||||
<strong>
|
|
||||||
{{ __('install.finish.env_manual', ['file' => base_path('.env')]) }}
|
|
||||||
</strong>
|
|
||||||
<div class="text-right mt-3">
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-light text-muted copy-btn"
|
|
||||||
data-clipboard-target="#env-content"
|
|
||||||
data-toggle="tooltip"
|
|
||||||
data-placement="bottom"
|
|
||||||
data-trigger="manual"
|
|
||||||
data-title="{{ __('install.finish.copied') }}"
|
|
||||||
>
|
|
||||||
<i class="fa-solid fa-clipboard"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<pre id="env-content" class="card bg-light p-3">{{ $env }}</pre>
|
<div class="card-body">
|
||||||
</div>
|
<form id="settings">
|
||||||
@endif
|
@if($can_update)
|
||||||
</div>
|
<div class="mb-3">
|
||||||
<div class="card mb-2">
|
<span>{{ __('settings.settings.update_channel.description') }}</span>
|
||||||
<div class="card-header h6" data-toggle="collapse" data-target="#config-file-text" aria-expanded="false">
|
<div class="custom-control custom-radio custom-control-inline">
|
||||||
<i class="fa-solid fa-lg fa-square-check text-success"></i>
|
<input type="radio" id="update_channel_daily" name="update_channel" class="custom-control-input" value="master" @config('update_channel', 'master') checked @endconfig>
|
||||||
{{ $config_message }}
|
<label class="custom-control-label" for="update_channel_daily">{{ __('settings.settings.update_channel.options.master') }}</label>
|
||||||
@if($config)<i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed pull-right"></i>@endif
|
</div>
|
||||||
</div>
|
<div class="custom-control custom-radio custom-control-inline">
|
||||||
@if($config)
|
<input type="radio" id="update_channel_monthly" name="update_channel" class="custom-control-input" value="release" @config('update_channel', 'release') checked @endconfig>
|
||||||
<div id="config-file-text" class="card-body collapse">
|
<label class="custom-control-label" for="update_channel_monthly">{{ __('settings.settings.update_channel.options.release') }}</label>
|
||||||
<strong>
|
</div>
|
||||||
{{ __('install.finish.config_not_required') }}
|
</div>
|
||||||
</strong>
|
@endif
|
||||||
<div class="text-right mt-3">
|
|
||||||
<button
|
<div class="mb-3">
|
||||||
class="btn btn-sm btn-light text-muted copy-btn"
|
<span>{{ __('settings.settings.site_style.description') }}</span>
|
||||||
data-clipboard-target="#config-content"
|
<div class="custom-control custom-radio custom-control-inline">
|
||||||
data-toggle="tooltip"
|
<input type="radio" id="site_style_light" name="site_style" class="custom-control-input" value="light" @config('site_style', 'light') checked @endconfig>
|
||||||
data-placement="bottom"
|
<label class="custom-control-label" for="site_style_light">{{ __('settings.settings.site_style.options.light') }}</label>
|
||||||
data-trigger="manual"
|
</div>
|
||||||
data-title="{{ __('install.finish.copied') }}"
|
<div class="custom-control custom-radio custom-control-inline">
|
||||||
>
|
<input type="radio" id="site_style_dark" name="site_style" class="custom-control-input" value="dark" @config('site_style', 'dark') checked @endconfig>
|
||||||
<i class="fa-solid fa-clipboard"></i>
|
<label class="custom-control-label" for="site_style_dark">{{ __('settings.settings.site_style.options.dark') }}</label>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<pre id="config-content" class="card bg-light p-3">{{ $config }}</pre>
|
|
||||||
</div>
|
<div class="custom-control custom-checkbox mb-3">
|
||||||
@endif
|
<input type="checkbox" class="custom-control-input" id="usage_reporting" name="usage_reporting" @config('reporting.usage') checked @endconfig>
|
||||||
</div>
|
<label class="custom-control-label" for="usage_reporting"><a target="_blank" href="https://stats.librenms.org/">{{ __('settings.settings.reporting.usage.description') }}</a></label>
|
||||||
@if($success)
|
</div>
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
<div class="custom-control custom-checkbox mb-3">
|
||||||
<div class="alert alert-warning">
|
<input type="checkbox" class="custom-control-input" id="error_reporting" name="error_reporting" @config('reporting.error') checked @endconfig>
|
||||||
<p>{{ __('install.finish.not_finished') }}</p>
|
<label class="custom-control-label" for="error_reporting">{{ __('settings.settings.reporting.error.description') }}</label>
|
||||||
<p>
|
</div>
|
||||||
{{ explode('|', __('install.finish.validate', ['validate' => '|']), 2)[0] }}
|
|
||||||
<a href="{{ url('validate') }}">{{ __('install.finish.validate_link') }}</a>
|
<div>
|
||||||
{{ explode('|', __('install.finish.validate', ['validate' => '|']), 2)[1] }}
|
<button type="button" class="btn btn-primary finalize-buttons">{{ __('install.finish.finish') }}</button>
|
||||||
</p>
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div id="finished" class="modal" tabindex="-1">
|
||||||
<div class="row">
|
<div class="modal-dialog">
|
||||||
<div class="col-12">
|
<div class="modal-content">
|
||||||
<div class="alert alert-success">
|
<div class="modal-header">
|
||||||
<p>{{ __('install.finish.thanks') }}</p>
|
<h5 class="modal-title"></h5>
|
||||||
{{ explode('|', __('install.finish.statistics', ['about' => '|']), 2)[0] }}
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
<a href="{{ url('about') }}">{{ __('install.finish.statistics_link') }}</a>
|
<span aria-hidden="true">×</span>
|
||||||
{{ explode('|', __('install.finish.statistics', ['about' => '|']), 2)[1] }}
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="card mb-2">
|
||||||
|
<div id="env-header" class="card-header h6" data-toggle="collapse" data-target="#env-file-text" aria-expanded="false">
|
||||||
|
<i id="env-icon" class="fa-solid fa-lg"></i>
|
||||||
|
<span id="env-message"></span>
|
||||||
|
<span id="env-chevron" class="float-right"><i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed"></i></span>
|
||||||
|
</div>
|
||||||
|
<div id="env-file-text" class="card-body collapse">
|
||||||
|
<button class="btn btn-primary float-right finalize-buttons">{{ __('install.finish.retry') }}</button>
|
||||||
|
<strong>
|
||||||
|
{{ __('install.finish.env_manual', ['file' => base_path('.env')]) }}
|
||||||
|
</strong>
|
||||||
|
<div class="text-right mt-3">
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-light text-muted copy-btn"
|
||||||
|
data-clipboard-target="#env-content"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
data-placement="bottom"
|
||||||
|
data-trigger="manual"
|
||||||
|
data-title="{{ __('install.finish.copied') }}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-clipboard"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<pre id="env-content" class="card bg-light p-3"></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-2">
|
||||||
|
<div class="card-header h6" data-toggle="collapse" data-target="#config-file-text" aria-expanded="false">
|
||||||
|
<i id="config-icon" class="fa-solid fa-lg"></i>
|
||||||
|
<span id="config-message"></span>
|
||||||
|
<span id="config-chevron" class="float-right"><i class="fa-solid fa-lg fa-chevron-down rotate-if-collapsed"></i></span>
|
||||||
|
</div>
|
||||||
|
<div id="config-file-text" class="card-body collapse">
|
||||||
|
<strong>
|
||||||
|
{{ __('install.finish.config_not_required') }}
|
||||||
|
</strong>
|
||||||
|
<div class="text-right mt-3">
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-light text-muted copy-btn"
|
||||||
|
data-clipboard-target="#config-content"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
data-placement="bottom"
|
||||||
|
data-trigger="manual"
|
||||||
|
data-title="{{ __('install.finish.copied') }}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-clipboard"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<pre id="config-content" class="card bg-light p-3"></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="success-message">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<i class="fa-solid fa-2x fa-heart" style="color: #ff4033;"></i>
|
||||||
|
<span class="h4 align-text-bottom">{{ __('install.finish.thanks') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="modal-retry" type="button" class="btn btn-primary finalize-buttons">{{ __('install.finish.retry') }}</button>
|
||||||
|
<div id="modal-finished">
|
||||||
|
<a href="{{ route('home') }}">
|
||||||
|
<button type="button" class="btn btn-secondary">{{ __('install.finish.dashboard') }}</button>
|
||||||
|
</a>
|
||||||
|
<a href="{{ url('validate') }}">
|
||||||
|
<button type="button" class="btn btn-primary">{{ __('install.finish.validate_button') }}</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('scripts')
|
@section('scripts')
|
||||||
<script>
|
<script>
|
||||||
var clipboard = new ClipboardJS('.copy-btn');
|
$('.finalize-buttons').on('click', function (e) {
|
||||||
clipboard.on('success', function(e) {
|
var data = $('#settings').serializeArray();
|
||||||
$(e.trigger).tooltip('show');
|
$.ajax('{{ route('install.finish.save') }}', {
|
||||||
setTimeout(() => $(e.trigger).tooltip('hide'), 2000);
|
method: 'post',
|
||||||
|
headers: {'X-CSRF-TOKEN': '{{ csrf_token() }}'},
|
||||||
|
data: data
|
||||||
|
}).done((result) => {
|
||||||
|
if (result.success) {
|
||||||
|
$('#env-header').attr('aria-expanded', 'false');
|
||||||
|
$('#env-file-text').addClass('show');
|
||||||
|
$('#success-message').show();
|
||||||
|
$('.modal-title').text('{{ __('install.finish.success') }}')
|
||||||
|
$('#modal-retry').hide();
|
||||||
|
$('#modal-finished').show();
|
||||||
|
} else {
|
||||||
|
$('#env-header').attr('aria-expanded', 'true');
|
||||||
|
$('#env-file-text').removeClass('show');
|
||||||
|
$('#success-message').hide();
|
||||||
|
$('.modal-title').text('{{ __('install.finish.failed') }}')
|
||||||
|
$('#modal-retry').show();
|
||||||
|
$('#modal-finished').hide();
|
||||||
|
}
|
||||||
|
|
||||||
e.clearSelection();
|
$('#env-message').text(result.env_message);
|
||||||
});
|
$('#env-content').text(result.env);
|
||||||
|
if (result.env) {
|
||||||
|
$('#env-chevron').show();
|
||||||
|
$('#env-file-text').removeAttr('style').addClass('show');
|
||||||
|
$('#env-icon').removeClass(['fa-square-check', 'text-success']).addClass(['fa-rectangle-xmark', 'text-danger']);
|
||||||
|
} else {
|
||||||
|
$('#env-file-text').hide();
|
||||||
|
$('#env-chevron').hide();
|
||||||
|
$('#env-icon').addClass(['fa-square-check', 'text-success']).removeClass(['fa-rectangle-xmark', 'text-danger']);
|
||||||
|
}
|
||||||
|
|
||||||
clipboard.on('error', function(e) {
|
$('#config-message').text(result.config_message);
|
||||||
$(e.trigger).data('title', '{{ __('install.finish.manual_copy') }}').tooltip('show');
|
$('#config-content').text(result.config);
|
||||||
setTimeout(() => $(e.trigger).tooltip('hide'), 2000);
|
if (result.config) {
|
||||||
});
|
$('#config-file-text').removeAttr('style');
|
||||||
</script>
|
$('#config-chevron').show();
|
||||||
|
$('#config-icon').removeClass(['fa-square-check', 'text-success']).addClass(['fa-rectangle-xmark', 'text-danger']);
|
||||||
|
} else {
|
||||||
|
$('#config-file-text').hide();
|
||||||
|
$('#config-chevron').hide();
|
||||||
|
$('#config-icon').addClass(['fa-square-check', 'text-success']).removeClass(['fa-rectangle-xmark', 'text-danger']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#finished').modal('show')
|
||||||
|
}).fail(function (output) {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var clipboard = new ClipboardJS('.copy-btn');
|
||||||
|
clipboard.on('success', function (e) {
|
||||||
|
$(e.trigger).tooltip('show');
|
||||||
|
setTimeout(() => $(e.trigger).tooltip('hide'), 2000);
|
||||||
|
|
||||||
|
e.clearSelection();
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboard.on('error', function (e) {
|
||||||
|
$(e.trigger).data('title', '{{ __('install.finish.manual_copy') }}').tooltip('show');
|
||||||
|
setTimeout(() => $(e.trigger).tooltip('hide'), 2000);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
@@ -51,7 +51,8 @@ Route::group(['middleware' => ['auth'], 'guard' => 'auth'], function () {
|
|||||||
Route::get('locations', 'LocationController@index');
|
Route::get('locations', 'LocationController@index');
|
||||||
Route::resource('preferences', 'UserPreferencesController', ['only' => ['index', 'store']]);
|
Route::resource('preferences', 'UserPreferencesController', ['only' => ['index', 'store']]);
|
||||||
Route::resource('users', 'UserController');
|
Route::resource('users', 'UserController');
|
||||||
Route::get('about', 'AboutController@index');
|
Route::get('about', [\App\Http\Controllers\AboutController::class, 'index'])->name('about');
|
||||||
|
Route::delete('reporting', [\App\Http\Controllers\AboutController::class, 'clearReportingData'])->name('reporting.clear');
|
||||||
Route::get('authlog', 'UserController@authlog');
|
Route::get('authlog', 'UserController@authlog');
|
||||||
Route::get('overview', 'OverviewController@index')->name('overview');
|
Route::get('overview', 'OverviewController@index')->name('overview');
|
||||||
Route::get('/', 'OverviewController@index')->name('home');
|
Route::get('/', 'OverviewController@index')->name('home');
|
||||||
@@ -227,6 +228,7 @@ Route::group(['prefix' => 'install', 'namespace' => 'Install'], function () {
|
|||||||
Route::get('/user', 'MakeUserController@index')->name('install.user');
|
Route::get('/user', 'MakeUserController@index')->name('install.user');
|
||||||
Route::get('/finish', 'FinalizeController@index')->name('install.finish');
|
Route::get('/finish', 'FinalizeController@index')->name('install.finish');
|
||||||
|
|
||||||
|
Route::post('/finish', 'FinalizeController@saveConfig')->name('install.finish.save');
|
||||||
Route::post('/user/create', 'MakeUserController@create')->name('install.action.user');
|
Route::post('/user/create', 'MakeUserController@create')->name('install.action.user');
|
||||||
Route::post('/database/test', 'DatabaseController@test')->name('install.acton.test-database');
|
Route::post('/database/test', 'DatabaseController@test')->name('install.acton.test-database');
|
||||||
Route::get('/ajax/database/migrate', 'DatabaseController@migrate')->name('install.action.migrate');
|
Route::get('/ajax/database/migrate', 'DatabaseController@migrate')->name('install.action.migrate');
|
||||||
|
Reference in New Issue
Block a user