mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Add lnms commands to get and set config settings (#10534)
* add lnms commands to get and set config settings lnms config:get and lnms config:set Note: you cannot override settings in config.php * Update to check setting exists and value validation rules.
This commit is contained in:
@ -297,6 +297,23 @@ class Config
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget a key and all it's descendants from persistent storage.
|
||||
* This will effectively set it back to default.
|
||||
*
|
||||
* @param string $key
|
||||
* @return int|false
|
||||
*/
|
||||
public static function erase($key)
|
||||
{
|
||||
self::forget($key);
|
||||
try {
|
||||
return \App\Models\Config::withChildren($key)->delete();
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a setting is set
|
||||
*
|
||||
|
@ -70,11 +70,13 @@ class DynamicConfigItem implements \ArrayAccess
|
||||
} elseif ($this->type == 'boolean') {
|
||||
return filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null;
|
||||
} elseif ($this->type == 'integer') {
|
||||
return filter_var($value, FILTER_VALIDATE_INT) || $value === "0" || $value === 0;
|
||||
return (!is_bool($value) && filter_var($value, FILTER_VALIDATE_INT)) || $value === "0" || $value === 0;
|
||||
} elseif ($this->type == 'select') {
|
||||
return in_array($value, array_keys($this->options));
|
||||
} elseif ($this->type == 'email') {
|
||||
return filter_var($value, FILTER_VALIDATE_EMAIL);
|
||||
} elseif ($this->type == 'array') {
|
||||
return is_array($value); // this should probably have more complex validation via validator rules
|
||||
} elseif (in_array($this->type, ['text', 'password'])) {
|
||||
return true;
|
||||
}
|
||||
@ -185,7 +187,7 @@ class DynamicConfigItem implements \ArrayAccess
|
||||
{
|
||||
return $this->validate
|
||||
? implode(" \n", $this->buildValidator($value)->messages()->get('value'))
|
||||
: __('settings.validate.' . $this->type, ['id' => $this->name, 'value' => is_array($value) ? json_encode($value) : $value]);
|
||||
: __('settings.validate.' . $this->type, ['id' => $this->name, 'value' => json_encode($value)]);
|
||||
}
|
||||
|
||||
// ArrayAccess functions
|
||||
|
54
app/Console/Commands/GetConfigCommand.php
Normal file
54
app/Console/Commands/GetConfigCommand.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\LnmsCommand;
|
||||
use LibreNMS\Config;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
class GetConfigCommand extends LnmsCommand
|
||||
{
|
||||
protected $name = 'config:get';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->addArgument('setting', InputArgument::OPTIONAL);
|
||||
$this->addOption('json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$setting = $this->argument('setting');
|
||||
if ($this->option('json')) {
|
||||
$this->line($setting ? json_encode(Config::get($setting)) : Config::toJson());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$setting) {
|
||||
throw new \RuntimeException('Not enough arguments (missing: "setting").');
|
||||
}
|
||||
|
||||
if (Config::has($setting)) {
|
||||
$output = Config::get($setting);
|
||||
if (!is_string($output)) {
|
||||
$output = var_export($output, 1);
|
||||
}
|
||||
|
||||
$this->line($output);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
82
app/Console/Commands/SetConfigCommand.php
Normal file
82
app/Console/Commands/SetConfigCommand.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\LnmsCommand;
|
||||
use LibreNMS\Config;
|
||||
use LibreNMS\DB\Eloquent;
|
||||
use LibreNMS\Util\DynamicConfig;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
class SetConfigCommand extends LnmsCommand
|
||||
{
|
||||
protected $name = 'config:set';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->addArgument('setting', InputArgument::REQUIRED);
|
||||
$this->addArgument('value', InputArgument::OPTIONAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(DynamicConfig $definition)
|
||||
{
|
||||
$setting = $this->argument('setting');
|
||||
$value = $this->argument('value');
|
||||
|
||||
if (!$definition->isValidSetting($setting)) {
|
||||
$this->error(__('This is not a valid setting. Please check your spelling'));
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!Eloquent::isConnected()) {
|
||||
$this->error(__('Database is not connected'));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!$value) {
|
||||
if ($this->confirm(__('Reset :setting to the default?', ['setting' => $setting]))) {
|
||||
Config::erase($setting);
|
||||
return 0;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
$value = $this->juggleType($value);
|
||||
$configItem = $definition->get($setting);
|
||||
if (!$configItem->checkValue($value)) {
|
||||
$this->error($configItem->getValidationMessage($value));
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (Config::persist($setting, $value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->error(__('Failed to set :setting', ['setting' => $setting]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the string input into the appropriate PHP native type
|
||||
*
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
private function juggleType($value)
|
||||
{
|
||||
$json = json_decode($value, true);
|
||||
return json_last_error() ? $value : $json;
|
||||
}
|
||||
}
|
@ -34,6 +34,17 @@ abstract class LnmsCommand extends Command
|
||||
{
|
||||
protected $developer = false;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->setDescription(__('commands.' . $this->getName() . '.description'));
|
||||
}
|
||||
|
||||
public function isHidden()
|
||||
{
|
||||
return $this->hidden || ($this->developer && $this->getLaravel()->environment() !== 'production');
|
||||
|
@ -69,7 +69,7 @@ class SettingsController extends Controller
|
||||
return $this->jsonResponse($id, ":id is not a valid setting", null, 400);
|
||||
}
|
||||
|
||||
$dbConfig = \App\Models\Config::where('config_name', 'like', "$id%")->get();
|
||||
$dbConfig = \App\Models\Config::withChildren($id)->get();
|
||||
if ($dbConfig->isEmpty()) {
|
||||
return $this->jsonResponse($id, ":id is not set", $config->get($id)->default, 400);
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ class Config extends BaseModel
|
||||
'config_default' => 'array'
|
||||
];
|
||||
|
||||
// ---- Accessors/Mutators ----
|
||||
|
||||
public function getConfigValueAttribute($value)
|
||||
{
|
||||
return json_decode($value);
|
||||
@ -47,4 +49,12 @@ class Config extends BaseModel
|
||||
{
|
||||
$this->attributes['config_value'] = json_encode($value, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
// ---- Query Scopes ----
|
||||
|
||||
public function scopeWithChildren($query, $name)
|
||||
{
|
||||
return $query->where('config_name', $name)
|
||||
->orWhere('config_name', 'like', "$name.%");
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'config:get' => [
|
||||
'description' => 'Get configuration value',
|
||||
'arguments' => [
|
||||
'setting' => 'setting to get value of in dot notation (example: snmp.community.0)',
|
||||
],
|
||||
'options' => [
|
||||
'json' => 'Output setting or entire config as json',
|
||||
],
|
||||
],
|
||||
'config:set' => [
|
||||
'description' => 'Set configuration value (or unset)',
|
||||
'arguments' => [
|
||||
'setting' => 'setting to set in dot notation (example: snmp.community.0)',
|
||||
'value' => 'value to set, unset setting if this is omitted',
|
||||
],
|
||||
],
|
||||
'user:add' => [
|
||||
'description' => 'Add a local user, you can only log in with this user if auth is set to mysql',
|
||||
'arguments' => [
|
||||
|
Reference in New Issue
Block a user