mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
consistency run through
This commit is contained in:
@@ -71,6 +71,10 @@ class ChecksController extends InstallationController implements InstallerStep
|
||||
|
||||
public function complete(): bool
|
||||
{
|
||||
if ($this->stepCompleted('checks')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->checkPhpVersion()) {
|
||||
return false;
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ class DatabaseController extends InstallationController implements InstallerStep
|
||||
|
||||
public function complete(): bool
|
||||
{
|
||||
if (session('install.database')) {
|
||||
if ($this->stepCompleted('database')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ namespace App\Http\Controllers\Install;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use LibreNMS\DB\Eloquent;
|
||||
use LibreNMS\Interfaces\InstallerStep;
|
||||
|
||||
class InstallationController extends Controller
|
||||
{
|
||||
@@ -39,10 +40,16 @@ class InstallationController extends Controller
|
||||
'finish' => \App\Http\Controllers\Install\FinalizeController::class,
|
||||
];
|
||||
|
||||
public function redirectToFirst()
|
||||
{
|
||||
$step = collect($this->filterActiveSteps())->keys()->first(null, 'checks');
|
||||
return redirect()->route("install.$step");
|
||||
}
|
||||
|
||||
public function redirectToIncomplete()
|
||||
{
|
||||
foreach ($this->stepStatus() as $step => $complete) {
|
||||
if (!$complete) {
|
||||
foreach ($this->filterActiveSteps() as $step => $controller) {
|
||||
if (!$controller->complete()) {
|
||||
return redirect()->route("install.$step");
|
||||
}
|
||||
}
|
||||
@@ -63,21 +70,19 @@ class InstallationController extends Controller
|
||||
/**
|
||||
* Init step info and return false if previous steps have not been completed.
|
||||
*
|
||||
* @return bool
|
||||
* @return bool if all previous steps have been completed
|
||||
*/
|
||||
final protected function initInstallStep()
|
||||
{
|
||||
if (is_string(config('librenms.install'))) {
|
||||
$this->steps = array_intersect_key($this->steps, array_flip(explode(',', config('librenms.install'))));
|
||||
}
|
||||
$this->filterActiveSteps();
|
||||
$this->configureDatabase();
|
||||
|
||||
foreach ($this->stepStatus() as $step => $completed) {
|
||||
foreach ($this->stepStatus() as $step => $complete) {
|
||||
if ($step == $this->step) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$completed) {
|
||||
if (!$complete) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -87,13 +92,21 @@ class InstallationController extends Controller
|
||||
|
||||
final protected function markStepComplete()
|
||||
{
|
||||
session(["install.$this->step" => true]);
|
||||
session()->save();
|
||||
if (!$this->stepCompleted($this->step)) {
|
||||
session(["install.$this->step" => true]);
|
||||
session()->save();
|
||||
}
|
||||
}
|
||||
|
||||
final protected function stepCompleted(string $step)
|
||||
{
|
||||
return (bool)session("install.$step");
|
||||
}
|
||||
|
||||
final protected function formatData($data = [])
|
||||
{
|
||||
$data['steps'] = $this->hydrateControllers();
|
||||
$data['step'] = $this->step;
|
||||
return $data;
|
||||
}
|
||||
|
||||
@@ -114,18 +127,32 @@ class InstallationController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
protected function filterActiveSteps()
|
||||
{
|
||||
if (is_string(config('librenms.install'))) {
|
||||
$this->steps = array_intersect_key($this->steps, array_flip(explode(',', config('librenms.install'))));
|
||||
}
|
||||
|
||||
return $this->steps;
|
||||
}
|
||||
|
||||
private function hydrateControllers()
|
||||
{
|
||||
$this->steps = array_map(function ($class) {
|
||||
return is_object($class) ? $class : app()->make($class);
|
||||
}, $this->steps);
|
||||
|
||||
return $this->steps;
|
||||
}
|
||||
|
||||
private function stepStatus()
|
||||
{
|
||||
$this->hydrateControllers();
|
||||
return array_map(function ($controller) {
|
||||
return $controller->complete();
|
||||
}, $this->steps);
|
||||
return array_map(function (InstallerStep $controller) {
|
||||
return [
|
||||
'enabled' => $controller->enabled(),
|
||||
'complete' => $controller->complete(),
|
||||
];
|
||||
}, $this->steps);
|
||||
}
|
||||
}
|
||||
|
@@ -26,9 +26,9 @@
|
||||
namespace App\Http\Controllers\Install;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use LibreNMS\DB\Eloquent;
|
||||
use LibreNMS\Interfaces\InstallerStep;
|
||||
|
||||
class MakeUserController extends InstallationController implements InstallerStep
|
||||
@@ -65,11 +65,20 @@ class MakeUserController extends InstallationController implements InstallerStep
|
||||
]);
|
||||
|
||||
try {
|
||||
$user = new User($request->only(['username', 'password', 'email']));
|
||||
$user->level = 10;
|
||||
$user->setPassword($request->get('password'));
|
||||
$res = $user->save();
|
||||
$message = $res ? trans('install.user.success') : trans('install.user.failure');
|
||||
// only allow the first admin to be created
|
||||
if (!$this->complete()) {
|
||||
$this->configureDatabase();
|
||||
$user = new User($request->only(['username', 'password', 'email']));
|
||||
$user->level = 10; // admin
|
||||
$user->setPassword($request->get('password'));
|
||||
$res = $user->save();
|
||||
|
||||
$message = trans('install.user.failure');
|
||||
if ($res) {
|
||||
$message = trans('install.user.success');
|
||||
$this->markStepComplete();
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$message = $e->getMessage();
|
||||
}
|
||||
@@ -79,12 +88,27 @@ class MakeUserController extends InstallationController implements InstallerStep
|
||||
|
||||
public function complete(): bool
|
||||
{
|
||||
return Eloquent::isConnected() && User::adminOnly()->exists();
|
||||
if ($this->stepCompleted('user')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($this->stepCompleted('database')) {
|
||||
$exists = User::adminOnly()->exists();
|
||||
if ($exists) {
|
||||
$this->markStepComplete();
|
||||
}
|
||||
return $exists;
|
||||
}
|
||||
} catch (QueryException $e) {
|
||||
//
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function enabled(): bool
|
||||
{
|
||||
return (bool)session('install.database');
|
||||
return $this->stepCompleted('database');
|
||||
}
|
||||
|
||||
public function icon(): string
|
||||
|
@@ -53,6 +53,10 @@ class CheckInstalled
|
||||
// redirect to install if not installed
|
||||
return redirect()->route('install');
|
||||
} elseif ($installed && $is_install_route) {
|
||||
// in case someone refreshes on the finish step
|
||||
if ($request->routeIs('install.finish')) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
throw new AuthorizationException('This should only be called during install');
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,5 @@
|
||||
@extends('layouts.install')
|
||||
|
||||
@section('title', trans('install.checks.title'))
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class=" col-8 offset-2">
|
||||
|
@@ -1,7 +1,5 @@
|
||||
@extends('layouts.install')
|
||||
|
||||
@section('title', trans('install.database.title'))
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@@ -73,7 +71,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" @if(!$valid_credentials) style="display: none" @endif>
|
||||
<div id="migrate-step" class="row" @if(!$valid_credentials) style="display: none" @endif>
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div id="db-form-header"
|
||||
@@ -95,12 +93,16 @@
|
||||
<i class="fa fa-lg fa-chevron-down rotate-if-collapsed fa-pull-right"></i>
|
||||
</div>
|
||||
<div id="migrate-container" class="card-body collapse @if(!$migrated) show @endif">
|
||||
<div class="mb-2 text-right">
|
||||
<button id="migrate-btn" type="button" class="btn btn-primary">
|
||||
@lang('install.migrate.migrate')
|
||||
</button>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div id="migrate-warning" class="alert alert-warning">@lang('install.migrate.building_interrupt')</div>
|
||||
</div>
|
||||
<div class="col-md-4 text-right">
|
||||
<button id="migrate-btn" type="button" class="btn btn-primary mt-1 mb-4">
|
||||
@lang('install.migrate.migrate')
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="migrate-warning" class="alert alert-warning">@lang('install.migrate.building_interrupt')</div>
|
||||
<textarea readonly id="db-update" class="form-control" rows="20" placeholder="@lang('install.migrate.wait')"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
@@ -123,7 +125,7 @@
|
||||
success: function (response) {
|
||||
if (response.result === 'ok') {
|
||||
$('#credential-status>i').attr('class', 'fa fa-lg fa-check-circle text-success');
|
||||
$('#migration-output').show();
|
||||
$('#migrate-step').show();
|
||||
$('#db-form-container').collapse('hide')
|
||||
} else {
|
||||
$('#credential-status>i').attr('class', 'fa fa-lg fa-times-circle text-danger')
|
||||
@@ -168,8 +170,7 @@
|
||||
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
||||
$('#migrate-warning').hide();
|
||||
checkStepStatus(function (status) {
|
||||
console.log(status);
|
||||
if (status.database) {
|
||||
if (status.database.complete) {
|
||||
$('#migrate-status>i').attr('class', 'fa fa-lg fa-check-circle text-success');
|
||||
$('#migrate-container').collapse('hide');
|
||||
}
|
||||
@@ -186,10 +187,6 @@
|
||||
#db-update {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
#retry-btn {
|
||||
display: none;
|
||||
}
|
||||
#migrate-warning {
|
||||
display: none;
|
||||
}
|
||||
|
@@ -1,7 +1,5 @@
|
||||
@extends('layouts.install')
|
||||
|
||||
@section('title', trans('install.finish.title'))
|
||||
|
||||
@section('content')
|
||||
<div class="card mb-2">
|
||||
<div class="card-header" data-toggle="collapse" data-target="#env-file-text" aria-expanded="false">
|
||||
|
@@ -1,7 +1,5 @@
|
||||
@extends('layouts.install')
|
||||
|
||||
@section('title', trans('install.user.title'))
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@@ -28,7 +26,7 @@
|
||||
@error('email')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success float-right">@lang('install.user.button')</button>
|
||||
<button type="submit" class="btn btn-primary float-right">@lang('install.user.button')</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,7 +1,5 @@
|
||||
@extends('layouts.install')
|
||||
|
||||
@section('title', trans('install.user.created'))
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-12 text-center p-5">
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
.primary-panel {
|
||||
padding: 0;
|
||||
border:0;
|
||||
border: 0;
|
||||
box-shadow: 3px 3px 30px #222;
|
||||
min-height: 540px;
|
||||
}
|
||||
@@ -35,6 +35,7 @@
|
||||
.card-img-top {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
#progress-icons {
|
||||
background: linear-gradient(to bottom, #EEEEEE 50%, white 50%)
|
||||
}
|
||||
@@ -51,16 +52,16 @@
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
background-color: lightgray;
|
||||
box-shadow:
|
||||
inset 0 6px 4px -5px black,
|
||||
inset 0 -6px 4px -7px black;
|
||||
box-shadow: inset 0 6px 4px -5px black,
|
||||
inset 0 -6px 4px -7px black;
|
||||
}
|
||||
|
||||
.install-progress.loop {
|
||||
box-shadow:
|
||||
inset 0 6px 4px -5px black,
|
||||
inset 0 -6px 4px -7px black,
|
||||
inset 8px 0 4px -6px grey; /* missing button shadow */
|
||||
box-shadow: inset 0 6px 4px -5px black,
|
||||
inset 0 -6px 4px -7px black,
|
||||
inset 8px 0 4px -6px grey; /* missing button shadow */
|
||||
}
|
||||
|
||||
.install-progress.complete {
|
||||
background-color: #db202e;
|
||||
}
|
||||
@@ -72,9 +73,11 @@
|
||||
.rotate-if-collapsed {
|
||||
transition: .4s transform ease-in-out;
|
||||
}
|
||||
|
||||
[data-toggle="collapse"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[data-toggle="collapse"][aria-expanded="true"] .rotate-if-collapsed {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
@@ -88,30 +91,33 @@
|
||||
<img class="card-img-top p-4" src="{{ asset(\LibreNMS\Config::get('title_image', "images/librenms_logo_light.svg")) }}" alt="LibreNMS">
|
||||
<div id="progress-icons" class="d-flex flex-row justify-content-around">
|
||||
<div class="install-progress complete"></div>
|
||||
@foreach($steps as $step => $controller)
|
||||
@foreach($steps as $name => $controller)
|
||||
<div>
|
||||
<a href="{{ route('install.' . $step) }}"
|
||||
class="install-enable-{{ $step }} btn btn-info btn-circle @if(!$controller->enabled($steps)) disabled @endif"
|
||||
title="@lang("install.$step.title")"
|
||||
<a href="{{ route('install.' . $name) }}"
|
||||
id="install-step-{{ $name }}"
|
||||
class="install-step btn btn-circle
|
||||
@if($step === $name) btn-outline-info @else btn-info @endif
|
||||
@if(!$controller->enabled()) disabled @endif"
|
||||
title="@lang("install.$name.title")"
|
||||
>
|
||||
<i class="fa fa-lg {{ $controller->icon() }}"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div id="progress-{{ $step }}-bar" class="install-progress loop @if($controller->complete()) complete @endif"></div>
|
||||
<div id="progress-{{ $name }}-bar" class="install-progress loop @if($controller->complete()) complete @endif"></div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center">
|
||||
<h2 id="step-title">@yield('title')</h2>
|
||||
<h2 id="step-title">@lang("install.$step.title")</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="error-box" class="col-12">
|
||||
@if(!empty($messages))
|
||||
@foreach($messages as $message)
|
||||
<div class="alert alert-danger">{{ $message }}</div>
|
||||
<div class="alert alert-danger">{{ $message }}</div>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
@@ -121,22 +127,43 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var step = '{{ $step }}';
|
||||
function checkStepStatus(callback) {
|
||||
$.ajax('{{ route('install.action.steps') }}')
|
||||
.success(function (data) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
if (data[key]) {
|
||||
$('.install-enable-' + key).removeClass('disabled');
|
||||
} else {
|
||||
$('.install-enable-' + key).addClass('disabled');
|
||||
}
|
||||
});
|
||||
.success(function (data) {
|
||||
var primary;
|
||||
Object.keys(data).forEach(function (key) {
|
||||
var classes = 'btn btn-circle';
|
||||
classes += (key === step ? ' btn-outline-info' : ' btn-info');
|
||||
|
||||
if (callback && typeof callback === "function") {
|
||||
callback(data);
|
||||
}
|
||||
})
|
||||
// mark buttons enabled
|
||||
if (!data[key].enabled) {
|
||||
classes += ' disabled';
|
||||
} else if (!data[key].complete && !primary) {
|
||||
// if this step is the first enabled, but not complete, mark it as primary
|
||||
primary = key
|
||||
}
|
||||
|
||||
$('#install-step-' + key).attr('class', classes);
|
||||
});
|
||||
|
||||
if (primary) {
|
||||
$('#install-step-' + primary)
|
||||
.removeClass('btn-info')
|
||||
.removeClass('btn-outline-info')
|
||||
.addClass(primary === step ? 'btn-outline-primary' : 'btn-primary');
|
||||
} else {
|
||||
// all complete
|
||||
$('.install-progress').addClass('complete')
|
||||
}
|
||||
|
||||
if (callback && typeof callback === "function") {
|
||||
callback(data);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
checkStepStatus();
|
||||
</script>
|
||||
@yield('scripts')
|
||||
</body>
|
||||
|
@@ -33,7 +33,7 @@ Route::group(['middleware' => ['auth'], 'guard' => 'auth'], function () {
|
||||
Route::get('about', 'AboutController@index');
|
||||
Route::get('authlog', 'UserController@authlog');
|
||||
Route::get('overview', 'OverviewController@index')->name('overview');
|
||||
Route::get('/', 'OverviewController@index');
|
||||
Route::get('/', 'OverviewController@index')->name('home');
|
||||
Route::match(['get', 'post'], 'device/{device}/{tab?}/{vars?}', 'DeviceController@index')
|
||||
->name('device')->where(['vars' => '.*']);
|
||||
|
||||
@@ -150,7 +150,7 @@ Route::group(['middleware' => ['auth'], 'guard' => 'auth'], function () {
|
||||
|
||||
// installation routes
|
||||
Route::group(['prefix' => 'install', 'namespace' => 'Install'], function () {
|
||||
Route::get('/', 'InstallationController@redirectToIncomplete')->name('install');
|
||||
Route::get('/', 'InstallationController@redirectToFirst')->name('install');
|
||||
Route::get('/checks', 'ChecksController@index')->name('install.checks');
|
||||
Route::get('/database', 'DatabaseController@index')->name('install.database');
|
||||
Route::get('/user', 'MakeUserController@index')->name('install.user');
|
||||
|
Reference in New Issue
Block a user