Skip to content

Commit

Permalink
Add Laravel to LibreNMS (librenms#8318)
Browse files Browse the repository at this point in the history
* Add Laravel to LibreNMS.

* Try to set permissions during initial install and first composer update to Laravel.

* Fix composer.lock
Fix missing db config keys

* Start building v1 layout
Port ajax_setresolution, inject csrf into jquery ajax calls
Layout works, building menu
Partially done.

* Fix device group list
remove stupid count relationships

* Print messages for common boot errors.
Don't log to laravel.log file.
Log to error_log until booted, then librenms.log

* Fix up some issues with Config loading
Start of custom directives

* Custom blade directives: config, notconfig, admin

* Preflight checks
Only load config files once.

* Update the composer.lock for php 5.6

* Menu through routing

* Start of alert menu

* Better alert scopes

* reduce cruft in models

* Alerting menu more or less working :D

* Fix style

* Improved preflight

* Fix chicken-eggs!

* Remove examples

* Better alert_rule status queries
Debugbar

* fix app.env check

* User Menu

* Settings bar (dropped refresh)
Search JS

* Toastr messages

* Rename preflight

* Use hasAccess(User) on most models.
Add port counts

* Missed a Preflight -> Checks rename

* Fix some formatting

* Boot Eloquent outside of Laravel
Use Eloquent for Config and Plugins so we don't have to connect with dbFacile inside Laravel.
Move locate_binary() into Config class

* Config WIP

* Try to fix a lot of config loading issues.

* Improve menu for non-admins removing unneeded menus
url() for all in menu

* Only use eloquent if it exists

* Include APP_URL in initial .env settings

* Implement Legacy User Provider

* Helper class for using Eloquent outside of Laravel.
Allows access to DB style queries too and checking the connection status.

* Fix up tests

* Fix device groups query

* Checking Travis

* copy config.test.php earlier

* dbFacile check config before connecting
Don't use exception to check if eloquent is connected, it gets grabbed by the exception handler.
Ignore missing config.php error.

* Fix config load with database is not migrated yet.

* Remove Config::load() from early boot.

* Use laravel config settings to init db (this prefers .env settings)
Fix bgp vars not set in menu
add _ide_helper.php to .gitignore

* Restrict dependencies to versions that support php 5.6

* Update ConfigTest

* Fix a couple of installation issues

* Add unique NODE_ID to .env

* Correct handling of title image

* Fix database config not loading. Thanks @laf

* Don't prepend /

* add class_exists checks for development service providers

* Fix config value casting

* Don't use functions that may not exist

* Update dbFacile.php

* d_echo may not be defined when Config used called.

* Add SELinux configuration steps
More detailed permissions check.
Check all and give complete corrective commands in one step.

* Ignore node_modules directory

* Re-add accidetal removal
  • Loading branch information
murrant authored May 9, 2018
1 parent 8afafe7 commit 1ad7f31
Show file tree
Hide file tree
Showing 132 changed files with 10,228 additions and 1,376 deletions.
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
APP_KEY=

#DB_HOST=
#DB_DATABASE=
#DB_USERNAME=
#DB_PASSWORD=

#APP_URL=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
!/.github/
!/.codeclimate.yml
!/.mention-bot
!/.env.example

# Others #
##########
Expand All @@ -25,7 +26,9 @@ nbproject
patches
!/lib/yaml
/vendor
/node_modules
composer.phar
_ide_helper.php

# Docs #
########
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ before_install:
- sudo apt-get -qq update
- sudo apt-get install -y snmp fping
- mysql -e 'CREATE DATABASE librenms_phpunit_78hunjuybybh;'
- cp tests/config/config.test.php config.php

install:
- composer install --prefer-dist --no-interaction
Expand Down
97 changes: 96 additions & 1 deletion LibreNMS/ComposerHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,27 @@

namespace LibreNMS;

use Composer\Script\Event;
use Composer\Installer\PackageEvent;
use Composer\Script\Event;

class ComposerHelper
{
public static function postRootPackageInstall(Event $event)
{
if (!file_exists('.env')) {
self::setPermissions();
self::populateEnv();
}
}

public static function postInstall(Event $event)
{
if (!file_exists('.env')) {
self::setPermissions();
self::populateEnv();
}
}

public static function preUpdate(Event $event)
{
if (!getenv('FORCE')) {
Expand All @@ -55,6 +71,85 @@ public static function preInstall(Event $event)
}
}


/**
* Initially populate .env file
*/
private static function populateEnv()
{
if (!file_exists('.env')) {
copy('.env.example', '.env');
self::exec('php artisan key:generate');

$config = [
'db_host' => '',
'db_port' => '',
'db_name' => '',
'db_user' => '',
'db_pass' => '',
'db_socket' => '',
'base_url' => '',
'user' => '',
'group' => '',
];

@include 'config.php';

self::setEnv([
'NODE_ID' => uniqid(),
'DB_HOST' => $config['db_host'],
'DB_PORT' => $config['db_port'],
'DB_USERNAME' => $config['db_user'],
'DB_PASSWORD' => $config['db_pass'],
'DB_DATABASE' => $config['db_name'],
'DB_SOCKET' => $config['db_socket'],
'APP_URL' => $config['base_url'],
'LIBRENMS_USER' => $config['user'],
'LIBRENMS_GROUP' => $config['group'],
]);
}
}

/**
* Set a setting in .env file
*
* @param array $settings KEY => value list of settings
* @param string $file
*/
private static function setEnv($settings, $file = '.env')
{
$content = file_get_contents($file);
if (substr($content, -1) !== "\n") {
$content .= PHP_EOL;
}

foreach ($settings as $key => $value) {
// only add non-empty settings
if (empty($value)) {
continue;
}

if (strpos($content, "$key=") !== false) {
// only replace ones that aren't already set for safety and uncomment
$content = preg_replace("/#?$key=\n/", "$key=$value\n", $content);
} else {
$content .= "$key=$value\n";
}
}

file_put_contents($file, $content);
}

private static function setPermissions()
{
$permissions_cmds = [
'setfacl -R -m g::rwx rrd/ logs/ storage/ bootstrap/cache/',
'setfacl -d -m g::rwx rrd/ logs/ storage/ bootstrap/cache/',
];

self::exec($permissions_cmds);
}

/**
* Run a command or array of commands and echo the command and output
*
Expand Down
134 changes: 107 additions & 27 deletions LibreNMS/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

namespace LibreNMS;

use App\Models\GraphType;
use Illuminate\Database\QueryException;
use LibreNMS\DB\Eloquent;

class Config
{
/**
Expand All @@ -39,16 +43,19 @@ public static function &load()
self::loadFiles();

// Make sure the database is connected
if (dbIsConnected()) {
if (Eloquent::isConnected() || (function_exists('dbIsConnected') && dbIsConnected())) {
// pull in the database config settings
self::mergeDb();

// load graph types from the database
self::loadGraphsFromDb();
}

// Process $config to tidy up
self::processConfig();
// process $config to tidy up
self::processConfig(true);
} else {
// just process $config
self::processConfig(false);
}

return $config;
}
Expand Down Expand Up @@ -80,7 +87,7 @@ private static function &loadFiles()
require $install_dir . '/includes/vmware_guestid.inc.php';

// Load user config
include $install_dir . '/config.php';
@include $install_dir . '/config.php';

return $config;
}
Expand Down Expand Up @@ -222,22 +229,45 @@ public static function getCombined($os, $key, $default = array())
* @param string $group webui group (only set when initially created)
* @param string $sub_group webui subgroup (only set when initially created)
*/
public static function set($key, $value, $persist = false, $default = '', $descr = '', $group = '', $sub_group = '')
public static function set($key, $value, $persist = false, $default = null, $descr = null, $group = null, $sub_group = null)
{
global $config;

if ($persist) {
$res = dbUpdate(array('config_value' => $value), 'config', '`config_name`=?', array($key));
if (!$res && !dbFetchCell('SELECT 1 FROM `config` WHERE `config_name`=?', array($key))) {
$insert = array(
'config_name' => $key,
'config_value' => $value,
'config_default' => $default,
'config_descr' => $descr,
'config_group' => $group,
'config_sub_group' => $sub_group,
);
dbInsert($insert, 'config');
if (Eloquent::isConnected()) {
try {
$config_array = collect([
'config_name' => $key,
'config_value' => $value,
'config_default' => $default,
'config_descr' => $descr,
'config_group' => $group,
'config_sub_group' => $sub_group,
])->filter(function ($value) {
return !is_null($value);
})->toArray();

\App\Models\Config::updateOrCreate(['config_name' => $key], $config_array);
} catch (QueryException $e) {
// possibly table config doesn't exist yet
global $debug;
if ($debug) {
echo $e;
}
}
} else {
$res = dbUpdate(array('config_value' => $value), 'config', '`config_name`=?', array($key));
if (!$res && !dbFetchCell('SELECT 1 FROM `config` WHERE `config_name`=?', array($key))) {
$insert = array(
'config_name' => $key,
'config_value' => $value,
'config_default' => $default,
'config_descr' => $descr,
'config_group' => $group,
'config_sub_group' => $sub_group,
);
dbInsert($insert, 'config');
}
}
}

Expand Down Expand Up @@ -292,10 +322,24 @@ private static function mergeDb()
{
global $config;

$db_config = array();
foreach (dbFetchRows('SELECT `config_name`,`config_value` FROM `config`') as $obj) {
self::assignArrayByPath($db_config, $obj['config_name'], $obj['config_value']);
$db_config = [];

if (Eloquent::isConnected()) {
try {
\App\Models\Config::get(['config_name', 'config_value'])
->each(function ($item) use (&$db_config) {
array_set($db_config, $item->config_name, $item->config_value);
});
} catch (QueryException $e) {
// possibly table config doesn't exist yet
}

} else {
foreach (dbFetchRows('SELECT `config_name`,`config_value` FROM `config`') as $obj) {
self::assignArrayByPath($db_config, $obj['config_name'], $obj['config_value']);
}
}

$config = array_replace_recursive($db_config, $config);
}

Expand All @@ -312,9 +356,9 @@ private static function assignArrayByPath(&$arr, $path, $value, $separator = '.'
{
// type cast value. Is this needed here?
if (filter_var($value, FILTER_VALIDATE_INT)) {
$value = (int) $value;
$value = (int)$value;
} elseif (filter_var($value, FILTER_VALIDATE_FLOAT)) {
$value = (float) $value;
$value = (float)$value;
} elseif (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null) {
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
Expand All @@ -333,8 +377,20 @@ private static function loadGraphsFromDb()
{
global $config;

if (Eloquent::isConnected()) {
try {
$graph_types = GraphType::all()->toArray();
} catch (QueryException $e) {
// possibly table config doesn't exist yet
$graph_types = [];
}
} else {
$graph_types = dbFetchRows('SELECT * FROM graph_types');
}

// load graph types from the database
foreach (dbFetchRows('SELECT * FROM graph_types') as $graph) {
foreach ($graph_types as $graph) {
$g = [];
foreach ($graph as $k => $v) {
if (strpos($k, 'graph_') == 0) {
// remove leading 'graph_' from column name
Expand All @@ -353,9 +409,9 @@ private static function loadGraphsFromDb()
* Proces the config after it has been loaded.
* Make sure certain variables have been set properly and
*
*
* @param bool $persist Save binary locations and other settings to the database.
*/
private static function processConfig()
private static function processConfig($persist = true)
{
if (!self::get('email_from')) {
self::set('email_from', '"' . self::get('project_name') . '" <' . self::get('email_user') . '@' . php_uname('n') . '>');
Expand Down Expand Up @@ -388,7 +444,7 @@ private static function processConfig()
// make sure we have full path to binaries in case PATH isn't set
foreach (array('fping', 'fping6', 'snmpgetnext', 'rrdtool') as $bin) {
if (!is_executable(self::get($bin))) {
self::set($bin, locate_binary($bin), true, $bin, "Path to $bin", 'external', 'paths');
self::set($bin, self::locateBinary($bin), $persist, $bin, "Path to $bin", 'external', 'paths');
}
}
}
Expand Down Expand Up @@ -421,7 +477,10 @@ private static function setDefault($key, $value, $format_values = [])
private static function deprecatedVariable($old, $new)
{
if (self::has($old)) {
d_echo("Copied deprecated config $old to $new\n");
global $debug;
if ($debug) {
echo "Copied deprecated config $old to $new\n";
}
self::set($new, self::get($old));
}
}
Expand Down Expand Up @@ -463,4 +522,25 @@ public static function getDatabaseSettings()

return array_intersect_key($config, $keys); // return only the db settings
}

/**
* Locate the actual path of a binary
*
* @param $binary
* @return mixed
*/
public static function locateBinary($binary)
{
if (!str_contains($binary, '/')) {
$output = `whereis -b $binary`;
$list = trim(substr($output, strpos($output, ':') + 1));
$targets = explode(' ', $list);
foreach ($targets as $target) {
if (is_executable($target)) {
return $target;
}
}
}
return $binary;
}
}
Loading

0 comments on commit 1ad7f31

Please sign in to comment.