diff --git a/app/Console/Commands/DeviceAdd.php b/app/Console/Commands/DeviceAdd.php index a3478b96ad..efc804ca3e 100644 --- a/app/Console/Commands/DeviceAdd.php +++ b/app/Console/Commands/DeviceAdd.php @@ -42,9 +42,9 @@ class DeviceAdd extends LnmsCommand $this->optionValues = [ 'transport' => ['udp', 'udp6', 'tcp', 'tcp6'], - 'port-association-mode' => PortAssociationMode::getModes(), - 'auth-protocol' => \LibreNMS\SNMPCapabilities::supportedAuthAlgorithms(), - 'privacy-protocol' => \LibreNMS\SNMPCapabilities::supportedCryptoAlgorithms(), + 'port-association-mode' => [PortAssociationMode::class, 'getModes'], + 'auth-protocol' => [\LibreNMS\SNMPCapabilities::class, 'supportedAuthAlgorithms'], + 'privacy-protocol' => [\LibreNMS\SNMPCapabilities::class, 'supportedCryptoAlgorithms'], ]; $this->addArgument('device spec', InputArgument::REQUIRED); diff --git a/app/Console/DynamicInputOption.php b/app/Console/DynamicInputOption.php new file mode 100644 index 0000000000..d433e41581 --- /dev/null +++ b/app/Console/DynamicInputOption.php @@ -0,0 +1,52 @@ +. + * + * @link https://www.librenms.org + * + * @copyright 2022 Tony Murray + * @author Tony Murray + */ + +namespace App\Console; + +use Symfony\Component\Console\Input\InputOption; + +class DynamicInputOption extends InputOption +{ + /** @var callable|null */ + private $valuesCallable; + + public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null, ?callable $valuesCallable = null) + { + $this->valuesCallable = $valuesCallable; + + parent::__construct($name, $shortcut, $mode, $description, $default); + } + + public function getDescription() + { + $description = parent::getDescription(); + + if (is_callable($this->valuesCallable)) { + $description .= ' [' . implode(', ', call_user_func($this->valuesCallable)) . ']'; + } + + return $description; + } +} diff --git a/app/Console/LnmsCommand.php b/app/Console/LnmsCommand.php index 21fc08dca4..b034c6df66 100644 --- a/app/Console/LnmsCommand.php +++ b/app/Console/LnmsCommand.php @@ -36,7 +36,7 @@ abstract class LnmsCommand extends Command { protected $developer = false; - /** @var string[][]|null */ + /** @var string[][]|callable[][]|null */ protected $optionValues; /** @@ -101,11 +101,8 @@ abstract class LnmsCommand extends Command $description = __('commands.' . $this->getName() . '.options.' . $name); } - if (isset($this->optionValues[$name])) { - $description .= ' [' . implode(', ', $this->optionValues[$name]) . ']'; - } - - parent::addOption($name, $shortcut, $mode, $description, $default); + // inject our custom InputOption to allow callable option enums + $this->getDefinition()->addOption(new DynamicInputOption($name, $shortcut, $mode, $description, $default, $this->getValuesCallable($name))); return $this; } @@ -118,8 +115,10 @@ abstract class LnmsCommand extends Command { // auto create option value rules if they don't exist if (isset($this->optionValues)) { - foreach ($this->optionValues as $option => $values) { - if (empty($rules[$option])) { + foreach (array_keys($this->optionValues) as $option) { + $callable = $this->getValuesCallable($option); + if (empty($rules[$option]) && $callable) { + $values = call_user_func($callable); $rules[$option] = Rule::in($values); $messages[$option . '.in'] = trans('commands.lnms.validation-errors.optionValue', [ 'option' => $option, @@ -158,4 +157,20 @@ abstract class LnmsCommand extends Command } } } + + private function getValuesCallable(string $name): ?callable + { + if (empty($this->optionValues[$name])) { + return null; + } + + $values = $this->optionValues[$name]; + if (is_callable($values)) { + return $values; + } + + return function () use ($values) { + return $values; + }; + } }