diff --git a/application/clicommands/CheckCommand.php b/application/clicommands/CheckCommand.php index 33d09dc0..0485b144 100644 --- a/application/clicommands/CheckCommand.php +++ b/application/clicommands/CheckCommand.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Clicommands; +use Exception; use gipfl\Cli\Screen; use Icinga\Date\DateFormatter; use Icinga\Exception\NotFoundError; @@ -12,10 +13,10 @@ use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Db\CheckRelatedLookup; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState; use Icinga\Module\Vspheredb\Monitoring\CheckRunner; use Icinga\Module\Vspheredb\Monitoring\Health\ServerConnectionInfo; use Icinga\Module\Vspheredb\Monitoring\Health\VCenterInfo; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; use InvalidArgumentException; use Ramsey\Uuid\Uuid; @@ -28,18 +29,20 @@ class CheckCommand extends Command { use CheckPluginHelper; - /** @var Db */ - protected $db; + protected ?Db $db = null; /** * Check vSphereDB daemon health + * + * @return void */ - public function healthAction() + public function healthAction(): void { $this->run(function () { $migrations = Db::migrationsForDb($this->db()); if (! $migrations->hasSchema()) { $this->addProblem('CRITICAL', 'Database has no vSphereDB schema'); + return resolve(null); } if ($migrations->hasPendingMigrations()) { @@ -57,15 +60,15 @@ public function healthAction() } if (count($vCenters) > 1) { - if ($this->getState() === 0) { - $this->prependMessage('All vCenters/ESXi Hosts are connected'); - } else { - $this->prependMessage('There are problems with some vCenters/ESXi Host connections'); - } + $this->prependMessage( + $this->getState() === 0 + ? 'All vCenters/ESXi Hosts are connected' + : 'There are problems with some vCenters/ESXi Host connections' + ); } - }, function (\Exception $e) { + }, function (Exception $e) { $message = $e->getMessage(); - if (preg_match('/^Unable to connect/', $message)) { + if (str_starts_with($message, 'Unable to connect')) { $message = "Daemon not running? $message"; } $this->addProblem('CRITICAL', $message); @@ -82,8 +85,10 @@ public function healthAction() * USAGE * * icingacli vspheredb check vcenterconnection --vCenter + * + * @return void */ - public function vcenterconnectionAction() + public function vcenterconnectionAction(): void { $this->run(function () { $vcenter = VCenterInfo::fetchOne( @@ -105,20 +110,16 @@ public function vcenterconnectionAction() * USAGE * * icingacli vspheredb check host [--name |--uuid ] [--ruleset ] [--rule [/]] + * + * @return void */ - public function hostAction() + public function hostAction(): void { $this->run(function () { $uuid = $this->params->get('uuid'); - if ($uuid !== null) { - $params = [ - 'uuid' => Uuid::fromString($uuid)->getBytes() - ]; - } else { - $params = [ - 'host_name' => $this->params->getRequired('name') - ]; - } + $params = $uuid !== null + ? ['uuid' => Uuid::fromString($uuid)->getBytes()] + : ['host_name' => $this->params->getRequired('name')]; $host = $this->lookup()->findOneBy('HostSystem', $params); $this->runChecks($host); }); @@ -130,8 +131,10 @@ public function hostAction() * USAGE * * icingacli vspheredb check hosts + * + * @return void */ - public function hostsAction() + public function hostsAction(): void { $this->showOverallStatusForProblems( $this->lookup()->listNonGreenObjects('HostSystem') @@ -144,8 +147,10 @@ public function hostsAction() * USAGE * * icingacli vspheredb check vm [--name |--uuid ] [--ruleset ] [--rule [/]] + * + * @return void */ - public function vmAction() + public function vmAction(): void { $this->run(function () { $uuid = $this->params->get('uuid'); @@ -174,8 +179,10 @@ public function vmAction() * USAGE * * icingacli vspheredb check vms + * + * @return void */ - public function vmsAction() + public function vmsAction(): void { $this->showOverallStatusForProblems( $this->lookup()->listNonGreenObjects('VirtualMachine') @@ -188,20 +195,16 @@ public function vmsAction() * USAGE * * icingacli vspheredb check datastore [--name |--uuid ] [--ruleset ] [--rule [/]] + * + * @return void */ - public function datastoreAction() + public function datastoreAction(): void { $this->run(function () { $uuid = $this->params->get('uuid'); - if ($uuid !== null) { - $params = [ - 'uuid' => Uuid::fromString($uuid)->getBytes() - ]; - } else { - $params = [ - 'object_name' => $this->params->getRequired('name') - ]; - } + $params = $uuid !== null + ? ['uuid' => Uuid::fromString($uuid)->getBytes()] + : ['object_name' => $this->params->getRequired('name')]; $datastore = $this->lookup()->findOneBy('Datastore', $params); $this->runChecks($datastore); }); @@ -213,15 +216,22 @@ public function datastoreAction() * USAGE * * icingacli vspheredb check datastores + * + * @return void */ - public function datastoresAction() + public function datastoresAction(): void { $this->showOverallStatusForProblems( $this->lookup()->listNonGreenObjects('Datastore') ); } - protected function runChecks(BaseDbObject $object) + /** + * @param BaseDbObject $object + * + * @return never + */ + protected function runChecks(BaseDbObject $object): never { $runner = new CheckRunner($this->db()); if ($section = $this->params->get(CheckRunner::RULESET_NAME_PARAMETER)) { @@ -244,10 +254,19 @@ protected function runChecks(BaseDbObject $object) } $result = $runner->check($object); echo $this->colorizeOutput($result->getOutput()) . PHP_EOL; + exit($result->getState()->getExitCode()); } - protected static function assertString($string, string $label) + /** + * @param mixed $string + * @param string $label + * + * @return void + * + * @throws InvalidArgumentException + */ + protected static function assertString(mixed $string, string $label): void { if (! is_string($string)) { throw new InvalidArgumentException("$label must be a string"); @@ -257,9 +276,10 @@ protected static function assertString($string, string $label) /** * @param VCenterInfo $vcenter * @param array> $connections + * * @return void */ - protected function checkVCenterConnection(VCenterInfo $vcenter, array $connections) + protected function checkVCenterConnection(VCenterInfo $vcenter, array $connections): void { $vcenterId = $vcenter->id; $prefix = sprintf('%s, %s: ', $vcenter->name, $vcenter->software); @@ -282,7 +302,10 @@ protected function checkVCenterConnection(VCenterInfo $vcenter, array $connectio } } - protected function checkDaemonStatus() + /** + * @return void + */ + protected function checkDaemonStatus(): void { $db = $this->db()->getDbAdapter(); $daemon = $db->fetchRow( @@ -301,16 +324,26 @@ protected function checkDaemonStatus() } } + /** + * @param string $string + * + * @return string + */ protected function colorizeOutput(string $string): string { $screen = Screen::factory(); $pattern = '/\[(OK|WARNING|CRITICAL|UNKNOWN)]\s/'; return preg_replace_callback($pattern, function ($match) use ($screen) { - return '[' . $screen->colorize($match[1], (new CheckPluginState($match[1]))->getColor()) . '] '; + return '[' . $screen->colorize($match[1], CheckPluginState::from($match[1])->color()) . '] '; }, $string); } - protected function showOverallStatusForProblems($problems) + /** + * @param array $problems + * + * @return void + */ + protected function showOverallStatusForProblems(array $problems): void { $this->run(function () use ($problems) { if (empty($problems)) { @@ -324,7 +357,13 @@ protected function showOverallStatusForProblems($problems) }); } - protected function addProblematicObjectNames($color, $objects) + /** + * @param string $color + * @param array $objects + * + * @return void + */ + protected function addProblematicObjectNames(string $color, array $objects): void { $showMax = 5; $stateName = $this->getStateForColor($color); @@ -357,27 +396,26 @@ protected function addProblematicObjectNames($color, $objects) */ protected function getStateForColor(string $color): string { - $colors = [ - 'green' => 'OK', - 'gray' => 'CRITICAL', - 'yellow' => 'WARNING', - 'red' => 'CRITICAL', - ]; - - return $colors[$color]; + return match ($color) { + 'green' => 'OK', + 'gray', 'red' => 'CRITICAL', + 'yellow' => 'WARNING' + }; } + /** + * @return CheckRelatedLookup + */ protected function lookup(): CheckRelatedLookup { return new CheckRelatedLookup($this->db()); } + /** + * @return Db + */ protected function db(): Db { - if ($this->db === null) { - $this->db = Db::newConfiguredInstance(); - } - - return $this->db; + return $this->db ??= Db::newConfiguredInstance(); } } diff --git a/application/clicommands/Command.php b/application/clicommands/Command.php index 3b01416c..e6fe3499 100644 --- a/application/clicommands/Command.php +++ b/application/clicommands/Command.php @@ -15,30 +15,36 @@ use Icinga\Module\Vspheredb\Configuration; use Icinga\Module\Vspheredb\Daemon\RemoteClient; use React\EventLoop\Loop; +use React\EventLoop\LoopInterface; use React\Stream\WritableResourceStream; class Command extends CliCommand { - private $loopStarted = false; + private bool $loopStarted = false; - protected $logger; + protected ?Logger $logger = null; - /** @var RemoteClient */ - protected $remoteClient; + protected ?RemoteClient $remoteClient = null; - public function init() + public function init(): void { $this->app->getModuleManager()->loadEnabledModules(); $this->clearProxySettings(); $this->initializeLogger(); } - protected function loop() + /** + * @return LoopInterface + */ + protected function loop(): LoopInterface { return Loop::get(); } - protected function eventuallyStartMainLoop() + /** + * @return $this + */ + protected function eventuallyStartMainLoop(): static { if (! $this->loopStarted) { $this->loopStarted = true; @@ -48,7 +54,10 @@ protected function eventuallyStartMainLoop() return $this; } - protected function stopMainLoop() + /** + * @return $this + */ + protected function stopMainLoop(): static { if ($this->loopStarted) { $this->loopStarted = false; @@ -61,16 +70,15 @@ protected function stopMainLoop() /** * @return RemoteClient */ - protected function remoteClient() + protected function remoteClient(): RemoteClient { - if ($this->remoteClient === null) { - $this->remoteClient = new RemoteClient(Configuration::getSocketPath(), $this->loop()); - } - - return $this->remoteClient; + return $this->remoteClient ??= new RemoteClient(Configuration::getSocketPath(), $this->loop()); } - protected function initializeLogger() + /** + * @return void + */ + protected function initializeLogger(): void { $this->logger = $logger = new Logger(); $this->eventuallyFilterLog($this->logger); @@ -91,7 +99,12 @@ protected function initializeLogger() } } - protected function eventuallyFilterLog(Logger $logger) + /** + * @param Logger $logger + * + * @return void + */ + protected function eventuallyFilterLog(Logger $logger): void { /** @noinspection PhpStatementHasEmptyBodyInspection */ if ($this->isDebugging) { @@ -104,18 +117,24 @@ protected function eventuallyFilterLog(Logger $logger) } } - protected function isRpc() + /** + * @return bool + */ + protected function isRpc(): bool { return (bool) $this->params->get('rpc'); } - protected function clearProxySettings() + /** + * @return void + */ + protected function clearProxySettings(): void { $settings = [ 'http_proxy', 'https_proxy', 'HTTPS_PROXY', - 'ALL_PROXY', + 'ALL_PROXY' ]; foreach ($settings as $setting) { putenv("$setting="); @@ -124,11 +143,13 @@ protected function clearProxySettings() /** * @param string $msg + * * @return never-return */ public function fail($msg) { echo $this->screen->colorize("$msg\n", 'red'); + exit(1); } @@ -136,13 +157,16 @@ protected function requireExtension() { } - public function failFriendly($task, $error = 'unknown error', $subject = null) + /** + * @param string $task + * @param Exception|string $error + * @param ?string $subject + * + * @return void + */ + public function failFriendly(string $task, Exception|string $error = 'unknown error', ?string $subject = null): void { - if ($error instanceof Exception) { - $message = $error->getMessage(); - } else { - $message = $error; - } + $message = $error instanceof Exception ? $error->getMessage() : $error; if (!$this->isRpc()) { $this->fail($message); @@ -158,12 +182,19 @@ public function failFriendly($task, $error = 'unknown error', $subject = null) // This allows to flush streams, especially pending log messages $this->loop()->addTimer(0.1, function () { $this->stopMainLoop(); + exit(1); }); $this->eventuallyStartMainLoop(); } - protected function shorten($message, $length) + /** + * @param string $message + * @param int $length + * + * @return string + */ + protected function shorten(string $message, int $length): string { if (strlen($message) > $length) { return substr($message, 0, $length - 2) . '...'; @@ -172,7 +203,12 @@ protected function shorten($message, $length) return $message; } - protected function requiredParam($name) + /** + * @param string $name + * + * @return mixed + */ + protected function requiredParam(string $name): mixed { $value = $this->params->get($name); if ($value === null) { diff --git a/application/clicommands/DaemonCommand.php b/application/clicommands/DaemonCommand.php index 6cb56cb6..3de0a767 100644 --- a/application/clicommands/DaemonCommand.php +++ b/application/clicommands/DaemonCommand.php @@ -14,8 +14,10 @@ class DaemonCommand extends Command * USAGE * * icingacli vsphere daemon run [--verbose|--debug] + * + * @return void */ - public function runAction() + public function runAction(): void { $this->assertRequiredExtensionsAreLoaded(); $this->assertNoVcenterParam(); @@ -30,7 +32,10 @@ public function runAction() $this->eventuallyStartMainLoop(); } - protected function assertNoVcenterParam() + /** + * @return void + */ + protected function assertNoVcenterParam(): void { if ($this->params->get('vCenterId')) { $this->fail( @@ -40,7 +45,10 @@ protected function assertNoVcenterParam() } } - protected function assertRequiredExtensionsAreLoaded() + /** + * @return void + */ + protected function assertRequiredExtensionsAreLoaded(): void { $required = ['soap', 'posix', 'pcntl']; $missing = []; diff --git a/application/clicommands/DbCommand.php b/application/clicommands/DbCommand.php index 8e7c7a11..67c9e8b9 100644 --- a/application/clicommands/DbCommand.php +++ b/application/clicommands/DbCommand.php @@ -7,6 +7,7 @@ use gipfl\Log\IcingaWeb\IcingaLogger; use gipfl\Log\Logger; use gipfl\Log\Writer\JsonRpcConnectionWriter; +use gipfl\Protocol\JsonRpc\Handler\JsonRpcHandler; use gipfl\Protocol\JsonRpc\Handler\NamespacedPacketHandler; use gipfl\Protocol\JsonRpc\JsonRpcConnection; use gipfl\Protocol\NetString\StreamWrapper; @@ -20,7 +21,10 @@ */ class DbCommand extends Command { - public function runAction() + /** + * @return void + */ + public function runAction(): void { if (!$this->isRpc()) { $this->fail('This is an internal command and should not be called directly'); @@ -45,18 +49,27 @@ public function runAction() $this->loop()->run(); } - protected function prepareLogger() + /** + * @return Logger + */ + protected function prepareLogger(): Logger { $logger = new Logger(); $this->eventuallyFilterLog($logger); IcingaLogger::replace($logger); + return $logger; } /** * Prepares a JSON-RPC Connection on STDIN/STDOUT + * + * @param LoopInterface $loop + * @param JsonRpcHandler $handler + * + * @return JsonRpcConnection */ - protected function prepareJsonRpc(LoopInterface $loop, $handler) + protected function prepareJsonRpc(LoopInterface $loop, JsonRpcHandler $handler): JsonRpcConnection { return new JsonRpcConnection(new StreamWrapper( new ReadableResourceStream(STDIN, $loop), diff --git a/application/clicommands/HealthCommand.php b/application/clicommands/HealthCommand.php index 45019024..741f81a7 100644 --- a/application/clicommands/HealthCommand.php +++ b/application/clicommands/HealthCommand.php @@ -8,7 +8,10 @@ class HealthCommand extends Command { use CheckPluginHelper; - public function checkAction() + /** + * @return void + */ + public function checkAction(): void { $this->run(function () { $this->addProblem('UNKNOWN', 'Please use `icingacli vspheredb check vcenterconnection`'); diff --git a/application/clicommands/MigrationCommand.php b/application/clicommands/MigrationCommand.php index 89ce052a..9afbc944 100644 --- a/application/clicommands/MigrationCommand.php +++ b/application/clicommands/MigrationCommand.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Clicommands; +use gipfl\DbMigration\Migrations; use Icinga\Module\Vspheredb\Db; /** @@ -25,8 +26,10 @@ class MigrationCommand extends Command * * Exit code 0 means that there are pending migrations, code 1 that there * are no such. Use --verbose for human-readable output + * + * @return never */ - public function pendingAction() + public function pendingAction(): never { if ($count = $this->migrations()->countPendingMigrations()) { if ($this->isVerbose) { @@ -51,14 +54,20 @@ public function pendingAction() * Run any pending migrations * * All pending migrations will be silently applied + * + * @return never */ - public function runAction() + public function runAction(): never { $this->migrations()->applyPendingMigrations(); + exit(0); } - protected function migrations() + /** + * @return Migrations + */ + protected function migrations(): Migrations { return Db::migrationsForDb(Db::newConfiguredInstance()); } diff --git a/application/clicommands/PerfCommand.php b/application/clicommands/PerfCommand.php index 080e65f0..7d44f4d7 100644 --- a/application/clicommands/PerfCommand.php +++ b/application/clicommands/PerfCommand.php @@ -5,7 +5,7 @@ class PerfCommand extends Command { /** - * Deprecated. The main daemon now provides this functionality + * @deprecated The main daemon now provides this functionality */ public function influxdbAction() { diff --git a/application/clicommands/PerfdataconsumerCommand.php b/application/clicommands/PerfdataconsumerCommand.php index 02c8c61e..1df8e63f 100644 --- a/application/clicommands/PerfdataconsumerCommand.php +++ b/application/clicommands/PerfdataconsumerCommand.php @@ -2,12 +2,13 @@ namespace Icinga\Module\Vspheredb\Clicommands; +use Exception; use gipfl\Translation\StaticTranslator; use gipfl\Web\Form; use gipfl\ZfDbStore\ZfDbStore; +use GuzzleHttp\Psr7\ServerRequest; use Icinga\Data\ResourceFactory; use Icinga\Module\Vspheredb\Web\Form\PerfdataConsumerForm; -use GuzzleHttp\Psr7\ServerRequest; class PerfdataconsumerCommand extends Command { @@ -17,8 +18,10 @@ class PerfdataconsumerCommand extends Command * USAGE * * icingacli vspheredb perfdataconsumer create --implementation [--disabled] [--other ] + * + * @return void */ - public function createAction() + public function createAction(): void { $name = $this->params->shift(); if (strlen($name) === 0) { @@ -34,7 +37,7 @@ public function createAction() 'name' => $name, 'enabled' => $enabled ? 'y' : 'n', 'implementation' => $implementation, - 'submit' => 'Create', + 'submit' => 'Create' ] + $this->params->getParams(); if ($this->submitForm($params)) { echo "'$name' has been created\n"; @@ -44,7 +47,12 @@ public function createAction() $this->fail("Creating '$name' failed for unknown reasons"); } - protected function submitForm($params) + /** + * @param array $params + * + * @return bool + */ + protected function submitForm(array $params): bool { StaticTranslator::setNoTranslator(); $form = new PerfdataConsumerForm($this->loop(), $this->remoteClient(), $this->getStore()); @@ -56,10 +64,16 @@ protected function submitForm($params) ); } - protected function validateRequestWithForm(ServerRequest $request, Form $form) + /** + * @param ServerRequest $request + * @param Form $form + * + * @return bool + */ + protected function validateRequestWithForm(ServerRequest $request, Form $form): bool { $success = false; - $form->on($form::ON_SUCCESS, function () use (&$success) { + $form->on($form::ON_SUBMIT, function () use (&$success) { $success = true; }); $form->handleRequest($request); @@ -84,18 +98,27 @@ protected function validateRequestWithForm(ServerRequest $request, Form $form) return $success; } - protected function wantErrorMessage($message) + /** + * @param Exception|string $message + * + * @return string + */ + protected function wantErrorMessage(Exception|string $message): string { - if ($message instanceof \Exception) { + if ($message instanceof Exception) { return $message->getMessage(); } return $message; } - protected function getStore() + /** + * @return ZfDbStore + */ + protected function getStore(): ZfDbStore { $connection = ResourceFactory::create($this->Config()->get('db', 'resource')); + return new ZfDbStore($connection->getDbAdapter()); } } diff --git a/application/clicommands/VcenterCommand.php b/application/clicommands/VcenterCommand.php index a4abd415..87ee5210 100644 --- a/application/clicommands/VcenterCommand.php +++ b/application/clicommands/VcenterCommand.php @@ -5,7 +5,7 @@ class VcenterCommand extends Command { /** - * Deprecated + * @deprecated Please check documentation */ public function initializeAction() { diff --git a/application/controllers/AlarmsController.php b/application/controllers/AlarmsController.php index 5922e9da..4bab7a31 100644 --- a/application/controllers/AlarmsController.php +++ b/application/controllers/AlarmsController.php @@ -5,21 +5,21 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Url; use Icinga\Date\DateFormatter; -use Icinga\Module\Vspheredb\Web\Table\AlarmHistoryTable; use Icinga\Module\Vspheredb\Web\Controller; +use Icinga\Module\Vspheredb\Web\Table\AlarmHistoryTable; use Icinga\Module\Vspheredb\Web\Widget\AlarmHeatmap; use Icinga\Module\Vspheredb\Web\Widget\CalendarForEvents; class AlarmsController extends Controller { - public function init() + public function init(): void { $this->assertPermission('vspheredb/admin'); parent::init(); $this->handleTabs(); } - public function indexAction() + public function indexAction(): void { $this->actions()->add(Link::create( $this->translate('Calendar'), @@ -27,7 +27,7 @@ public function indexAction() $this->url()->getParams()->toArray(false), [ 'class' => 'icon-calendar', - 'data-base-target' => '_main', + 'data-base-target' => '_main' ] )); $day = $this->params->shift('day'); @@ -49,7 +49,7 @@ public function indexAction() $table->renderTo($this); } - public function heatmapAction() + public function heatmapAction(): void { $this->actions()->add(Link::create( $this->translate('Table'), @@ -57,7 +57,7 @@ public function heatmapAction() $this->url()->getParams()->toArray(false), [ 'class' => 'icon-th-list', - 'data-base-target' => '_main', + 'data-base-target' => '_main' ] )); $this->addTitle($this->translate('Alarm Heatmap')); @@ -68,7 +68,10 @@ public function heatmapAction() $this->content()->add(new CalendarForEvents($heatMap, $baseUrl, [255, 0, 0])); } - protected function handleTabs() + /** + * @return void + */ + protected function handleTabs(): void { $params = []; if ($day = $this->params->get('day')) { diff --git a/application/controllers/AnomaliesController.php b/application/controllers/AnomaliesController.php index 0b6911d2..8659f8eb 100644 --- a/application/controllers/AnomaliesController.php +++ b/application/controllers/AnomaliesController.php @@ -9,7 +9,7 @@ class AnomaliesController extends Controller { // TODO: Overbooked datastores - public function indexAction() + public function indexAction(): void { $this->assertPermission('vspheredb/admin'); $this->addSingleTab($this->translate('Anomalies')); @@ -19,34 +19,25 @@ public function indexAction() $this->addTable('guest_ip_address', $this->translate('Guest IP address')); } - protected function addTable($property, $title) + /** + * @param string $property + * @param string $title + * + * @return void + */ + protected function addTable(string $property, string $title): void { $table = VmsWithDuplicateProperty::create($this->db(), $property, $title); $count = count($table); if ($count) { $this->content()->add([ - Html::tag( - 'h1', - null, - sprintf( - '%d Virtual Machines with duplicate %s', - $count, - $title - ) - ), + Html::tag('h1', null, sprintf('%d Virtual Machines with duplicate %s', $count, $title)), $table ]); } else { $this->content()->add( - Html::tag( - 'h1', - null, - sprintf( - 'There are no Virtual Machines with duplicate %s', - $title - ) - ) + Html::tag('h1', null, sprintf('There are no Virtual Machines with duplicate %s', $title)) ); } } diff --git a/application/controllers/AsyncControllerHelper.php b/application/controllers/AsyncControllerHelper.php index 6f50c146..3b98174a 100644 --- a/application/controllers/AsyncControllerHelper.php +++ b/application/controllers/AsyncControllerHelper.php @@ -5,16 +5,23 @@ use Icinga\Module\Vspheredb\Configuration; use Icinga\Module\Vspheredb\Daemon\RemoteClient; use React\EventLoop\Loop; +use React\EventLoop\LoopInterface; use function React\Async\await; use function React\Promise\Timer\timeout; trait AsyncControllerHelper { - /** @var RemoteClient */ - protected $remoteClient; + protected ?RemoteClient $remoteClient = null; - protected function syncRpcCall($method, $params = [], $timeout = 30) + /** + * @param string $method + * @param array $params + * @param ?float $timeout + * + * @return mixed + */ + protected function syncRpcCall(string $method, array $params = [], ?float $timeout = 30): mixed { return await(timeout($this->remoteClient()->request($method, $params), $timeout)); } @@ -22,16 +29,15 @@ protected function syncRpcCall($method, $params = [], $timeout = 30) /** * @return RemoteClient */ - protected function remoteClient() + protected function remoteClient(): RemoteClient { - if ($this->remoteClient === null) { - $this->remoteClient = new RemoteClient(Configuration::getSocketPath(), $this->loop()); - } - - return $this->remoteClient; + return $this->remoteClient ??= new RemoteClient(Configuration::getSocketPath(), $this->loop()); } - protected function loop() + /** + * @return LoopInterface + */ + protected function loop(): LoopInterface { return Loop::get(); } diff --git a/application/controllers/ComputeClusterController.php b/application/controllers/ComputeClusterController.php index faf9c1dd..e745f4a6 100644 --- a/application/controllers/ComputeClusterController.php +++ b/application/controllers/ComputeClusterController.php @@ -3,23 +3,26 @@ namespace Icinga\Module\Vspheredb\Controllers; use Icinga\Authentication\Auth; +use Icinga\Exception\MissingParameterException; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\DbObject\ComputeCluster; use Icinga\Module\Vspheredb\Web\Controller; use Icinga\Module\Vspheredb\Web\Table\Objects\HostsTable; use Icinga\Module\Vspheredb\Web\Widget\AdditionalTableActions; use Icinga\Module\Vspheredb\Web\Widget\ComputeClusterHeader; use Icinga\Module\Vspheredb\Web\Widget\Summaries; +use ipl\Html\Attributes; class ComputeClusterController extends Controller { /** - * @throws \Icinga\Exception\MissingParameterException - * @throws \Icinga\Exception\NotFoundError + * @throws MissingParameterException + * @throws NotFoundError */ - public function indexAction() + public function indexAction(): void { $computeCluster = $this->addComputeCluster(); - $this->content()->addAttributes(['class' => 'host-info']); + $this->content()->addAttributes(Attributes::create(['class' => 'host-info'])); $table = new HostsTable($this->db(), $this->url()); (new AdditionalTableActions($table, Auth::getInstance(), $this->url())) ->appendTo($this->actions()); @@ -32,10 +35,11 @@ public function indexAction() /** * @return ComputeCluster - * @throws \Icinga\Exception\MissingParameterException - * @throws \Icinga\Exception\NotFoundError + * + * @throws MissingParameterException + * @throws NotFoundError */ - protected function addComputeCluster() + protected function addComputeCluster(): ComputeCluster { $computeCluster = ComputeCluster::loadWithUuid($this->params->getRequired('uuid'), $this->db()); $this->getRestrictionHelper()->assertAccessToVCenterUuidIsGranted($computeCluster->get('vcenter_uuid')); @@ -48,9 +52,12 @@ protected function addComputeCluster() /** * @param ComputeCluster $computeCluster - * @throws \Icinga\Exception\MissingParameterException + * + * @return void + * + * @throws MissingParameterException */ - protected function handleTabs(ComputeCluster $computeCluster) + protected function handleTabs(ComputeCluster $computeCluster): void { $hexId = $this->params->getRequired('uuid'); $this->tabs()->add('index', [ diff --git a/application/controllers/ConfigurationController.php b/application/controllers/ConfigurationController.php index 577ce732..cdcde141 100644 --- a/application/controllers/ConfigurationController.php +++ b/application/controllers/ConfigurationController.php @@ -2,17 +2,20 @@ namespace Icinga\Module\Vspheredb\Controllers; +use Exception; use gipfl\IcingaWeb2\Link; use gipfl\Web\Widget\Hint; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Polling\ApiConnection; +use Icinga\Module\Vspheredb\Web\Controller; use Icinga\Module\Vspheredb\Web\Form\ChooseDbResourceForm; use Icinga\Module\Vspheredb\Web\Form\MonitoringConnectionForm; use Icinga\Module\Vspheredb\Web\Table\MonitoredObjectMappingTable; use Icinga\Module\Vspheredb\Web\Table\Objects\VCenterServersTable; use Icinga\Module\Vspheredb\Web\Tabs\ConfigTabs; -use Icinga\Module\Vspheredb\Web\Controller; +use Icinga\Security\SecurityException; use Icinga\Web\Notification; +use ipl\Html\Contract\Form; use ipl\Html\Html; use Ramsey\Uuid\Uuid; @@ -21,13 +24,13 @@ class ConfigurationController extends Controller use AsyncControllerHelper; use RpcServerUpdateHelper; - public function init() + public function init(): void { $this->assertPermission('vspheredb/admin'); parent::init(); } - public function databaseAction() + public function databaseAction(): void { $this->addTitle($this->translate('vSphereDB Database Configuration')); $this->tabs(new ConfigTabs())->activate('database'); @@ -53,6 +56,7 @@ public function databaseAction() 'The database has no vSphereDB schema. Waiting for the Background Daemon' . ' to initialize the database' ))); + return; } @@ -61,6 +65,7 @@ public function databaseAction() 'The database has pending DB migrations. Please restart the Background' . ' daemon to apply them' ))); + return; } @@ -76,9 +81,9 @@ public function databaseAction() } /** - * @throws \Icinga\Security\SecurityException + * @throws SecurityException */ - public function serversAction() + public function serversAction(): void { $this->tabs(new ConfigTabs($this->db()))->activate('servers'); $this->setAutorefreshInterval(10); @@ -91,18 +96,13 @@ public function serversAction() $connections = $this->mapServerConnectionsToId($this->syncRpcCall('vsphere.getApiConnections')); foreach ($connections as $conns) { foreach ($conns as $conn) { - if ( - in_array($conn->state, [ - ApiConnection::STATE_INIT, - ApiConnection::STATE_LOGIN, - ]) - ) { + if (in_array($conn->state, [ApiConnection::STATE_INIT, ApiConnection::STATE_LOGIN])) { $this->setAutorefreshInterval(5); } } } $this->setAutorefreshInterval(5); - } catch (\Exception $e) { + } catch (Exception $e) { $connections = null; $this->content()->add( Hint::warning($this->translate('Got no connection information. Is the Damon running?')) @@ -123,7 +123,12 @@ public function serversAction() } } - protected function mapServerConnectionsToId($connections) + /** + * @param mixed $connections + * + * @return array + */ + protected function mapServerConnectionsToId(mixed $connections): array { $connectionsByServer = []; foreach ((array) $connections as $id => $connection) { @@ -138,7 +143,7 @@ protected function mapServerConnectionsToId($connections) return $connectionsByServer; } - public function monitoringAction() + public function monitoringAction(): void { $this->tabs(new ConfigTabs($this->db()))->activate('monitoring'); $this->actions()->add(Link::create( @@ -147,7 +152,7 @@ public function monitoringAction() null, [ 'class' => 'icon-plus', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ] )); $this->addTitle($this->translate('Monitoring Integration')); @@ -159,13 +164,11 @@ public function monitoringAction() $this->content()->add($wrapper); $table->renderTo($this); } else { - $this->content()->add(Hint::warning($this->translate( - 'No integration has been configured' - ))); + $this->content()->add(Hint::warning($this->translate('No integration has been configured'))); } } - public function monitoringconfigAction() + public function monitoringconfigAction(): void { $id = $this->params->get('id'); if ($id) { @@ -182,7 +185,7 @@ public function monitoringconfigAction() } $form = new MonitoringConnectionForm($this->db()); - $form->on(MonitoringConnectionForm::ON_SUCCESS, function (MonitoringConnectionForm $form) { + $form->on(Form::ON_SUBMIT, function (MonitoringConnectionForm $form) { // TODO: created, modified, nothing, %s // $this->getViewRenderer()->disable(); $this->redirectNow($this->url()->with('id', $form->getId())); diff --git a/application/controllers/DaemonController.php b/application/controllers/DaemonController.php index 0566d15f..faf4b4fa 100644 --- a/application/controllers/DaemonController.php +++ b/application/controllers/DaemonController.php @@ -2,26 +2,28 @@ namespace Icinga\Module\Vspheredb\Controllers; +use Exception; use gipfl\IcingaWeb2\Icon; use gipfl\Json\JsonString; use gipfl\Web\Widget\Hint; use Icinga\Date\DateFormatter; -use Icinga\Module\Vspheredb\Web\Form\LogLevelForm; -use Icinga\Module\Vspheredb\Web\Form\RestartDaemonForm; use Icinga\Module\Vspheredb\Format; use Icinga\Module\Vspheredb\Web\Controller; +use Icinga\Module\Vspheredb\Web\Form\LogLevelForm; +use Icinga\Module\Vspheredb\Web\Form\RestartDaemonForm; use Icinga\Module\Vspheredb\Web\Table\VsphereApiConnectionTable; use Icinga\Module\Vspheredb\Web\Tabs\MainTabs; use Icinga\Module\Vspheredb\WebUtil; use Icinga\Web\Notification; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\Html\Table; class DaemonController extends Controller { use AsyncControllerHelper; - public function indexAction() + public function indexAction(): void { $this->assertPermission('vspheredb/admin'); $this->setAutorefreshInterval(30); @@ -40,7 +42,10 @@ public function indexAction() ]); } - protected function prepareLogSettings() + /** + * @return ?array + */ + protected function prepareLogSettings(): ?array { $logLevelForm = new LogLevelForm($this->remoteClient(), $this->loop()); $logLevelForm->on($logLevelForm::ON_SUCCESS, function () { @@ -54,7 +59,10 @@ protected function prepareLogSettings() return null; } - protected function prepareDaemonInfo() + /** + * @return Hint|array + */ + protected function prepareDaemonInfo(): Hint|array { $db = $this->db()->getDbAdapter(); $daemon = $db->fetchRow( @@ -70,22 +78,26 @@ protected function prepareDaemonInfo() "Daemon keep-alive is outdated in our database, last refresh was %s", WebUtil::timeAgo($daemon->ts_last_refresh / 1000) )); - } else { - $restartForm = new RestartDaemonForm($this->remoteClient(), $this->loop()); - $restartForm->on($restartForm::ON_SUCCESS, function () { - Notification::success('Daemon has been asked to restart'); - $this->redirectNow($this->url()); - }); - $restartForm->handleRequest($this->getServerRequest()); - - return [$restartForm, $this->prepareProcessTable(JsonString::decode($daemon->process_info))]; } - } else { - return Hint::error($this->translate('Daemon is either not running or not connected to the Database')); + $restartForm = new RestartDaemonForm($this->remoteClient(), $this->loop()); + $restartForm->on($restartForm::ON_SUBMIT, function () { + Notification::success('Daemon has been asked to restart'); + $this->redirectNow($this->url()); + }); + $restartForm->handleRequest($this->getServerRequest()); + + return [$restartForm, $this->prepareProcessTable(JsonString::decode($daemon->process_info))]; } + + return Hint::error($this->translate('Daemon is either not running or not connected to the Database')); } - protected function prepareProcessTable($processes) + /** + * @param mixed $processes + * + * @return Table + */ + protected function prepareProcessTable(mixed $processes): Table { $table = new Table(); foreach ($processes as $pid => $process) { @@ -103,7 +115,10 @@ protected function prepareProcessTable($processes) return $table; } - protected function prepareLogWindow() + /** + * @return HtmlElement + */ + protected function prepareLogWindow(): HtmlElement { $db = $this->db()->getDbAdapter(); $lineCount = 1000; @@ -115,20 +130,19 @@ protected function prepareLogWindow() $logWindow = Html::tag('div', ['class' => 'logWindow'], $log); foreach ($logLines as $line) { $ts = $line->ts_create / 1000; - if ($ts + 3600 * 16 < time()) { - $tsFormatted = DateFormatter::formatDateTime($ts); - } else { - $tsFormatted = DateFormatter::formatTime($ts); - } - $log->add(Html::tag('div', [ - 'class' => $line->level - ], "$tsFormatted: " . $line->message)); + $tsFormatted = $ts + 3600 * 16 < time() + ? DateFormatter::formatDateTime($ts) + : DateFormatter::formatTime($ts); + $log->add(Html::tag('div', ['class' => $line->level], "$tsFormatted: " . $line->message)); } return $logWindow; } - protected function prepareCurlInfoTable() + /** + * @return Hint|Table|string + */ + protected function prepareCurlInfoTable(): Hint|Table|string { try { $table = new Table(); @@ -205,27 +219,34 @@ protected function prepareCurlInfoTable() */ } - protected function prepareVsphereConnectionTable() + /** + * @return Hint|VsphereApiConnectionTable + */ + protected function prepareVsphereConnectionTable(): Hint|VsphereApiConnectionTable { try { - $table = new VsphereApiConnectionTable(array_map(function ($row) { - return [ + $table = new VsphereApiConnectionTable(array_map( + fn($row) => [ 'vCenterId' => $row->vCenterId, 'server' => $row->server, - 'state' => $row->state . (isset($row->lastErrorMessage) ? ': ' . $row->lastErrorMessage : ''), - ]; - }, $this->syncRpcCall('vsphere.getApiConnections'))); + 'state' => $row->state . (isset($row->lastErrorMessage) ? ': ' . $row->lastErrorMessage : '') + ], + $this->syncRpcCall('vsphere.getApiConnections') + )); if ($table->count() === 0) { return Hint::info($this->translate('The vSphereDB Daemon is currently not polling any vCenter')); } return $table; - } catch (\Exception $exception) { + } catch (Exception $exception) { return Hint::error($exception->getMessage()); } } - protected function handleTabs() + /** + * @return void + */ + protected function handleTabs(): void { $action = $this->getRequest()->getControllerName(); $tabs = $this->tabs(new MainTabs($this->Auth(), $this->db())); diff --git a/application/controllers/DatacentersController.php b/application/controllers/DatacentersController.php index 965216bc..e920ceec 100644 --- a/application/controllers/DatacentersController.php +++ b/application/controllers/DatacentersController.php @@ -10,7 +10,7 @@ class DatacentersController extends ObjectsController { - public function indexAction() + public function indexAction(): void { $this->addSingleTab($this->translate('Datacenters')); $table = new DatacentersTable($this->db(), $this->url()); diff --git a/application/controllers/DatastoreController.php b/application/controllers/DatastoreController.php index 00fc3b9c..3b9a5f34 100644 --- a/application/controllers/DatastoreController.php +++ b/application/controllers/DatastoreController.php @@ -4,6 +4,8 @@ use gipfl\IcingaWeb2\Link; use gipfl\Web\Table\NameValueTable; +use Icinga\Exception\MissingParameterException; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Data\Anonymizer; use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\PathLookup; @@ -21,10 +23,10 @@ class DatastoreController extends Controller use SingleObjectMonitoring; /** - * @throws \Icinga\Exception\MissingParameterException - * @throws \Icinga\Exception\NotFoundError + * @throws MissingParameterException + * @throws NotFoundError */ - public function indexAction() + public function indexAction(): void { $ds = $this->addDatastore(); $lookup = new PathLookup($this->db()->getDbAdapter()); @@ -56,7 +58,7 @@ public function indexAction() $ds->get('capacity') - $ds->get('free_space') ), $this->translate('Uncommitted') => $this->bytes($ds->get('uncommitted')), - $this->translate('Sizing') => $this->sizingInfo($ds), + $this->translate('Sizing') => $this->sizingInfo($ds) ]); $vms = VmsOnDatastoreTable::create($ds); @@ -64,10 +66,10 @@ public function indexAction() } /** - * @throws \Icinga\Exception\MissingParameterException - * @throws \Icinga\Exception\NotFoundError + * @throws MissingParameterException + * @throws NotFoundError */ - public function eventsAction() + public function eventsAction(): void { $ds = $this->addDatastore(); $table = new EventHistoryTable($this->db()); @@ -75,17 +77,18 @@ public function eventsAction() ->renderTo($this); } - public function monitoringAction() + public function monitoringAction(): void { $this->showMonitoringDetails($this->addDatastore()); } /** * @return Datastore - * @throws \Icinga\Exception\MissingParameterException - * @throws \Icinga\Exception\NotFoundError + * + * @throws MissingParameterException + * @throws NotFoundError */ - protected function addDatastore() + protected function addDatastore(): Datastore { $ds = Datastore::loadWithUuid($this->params->getRequired('uuid'), $this->db()); $ds->object()->set('object_name', Anonymizer::anonymizeString($ds->object()->get('object_name'))); @@ -96,7 +99,10 @@ protected function addDatastore() return $ds; } - protected function handleTabs() + /** + * @return void + */ + protected function handleTabs(): void { $params = ['uuid' => $this->params->get('uuid')]; $this->tabs()->add('index', [ @@ -118,7 +124,12 @@ protected function sizingInfo(Datastore $ds) { } - protected function bytes($bytes) + /** + * @param $bytes + * + * @return string + */ + protected function bytes($bytes): string { return Format::bytes($bytes, Format::STANDARD_IEC); } diff --git a/application/controllers/DatastoresController.php b/application/controllers/DatastoresController.php index eca3565e..bab388f2 100644 --- a/application/controllers/DatastoresController.php +++ b/application/controllers/DatastoresController.php @@ -11,7 +11,7 @@ class DatastoresController extends ObjectsController { - public function indexAction() + public function indexAction(): void { $this->handleTabs(); $this->addTreeViewToggle(); @@ -35,7 +35,7 @@ public function indexAction() $this->content()->prepend($summaries); } - public function exportAction() + public function exportAction(): void { $this->sendExport('datastore'); } diff --git a/application/controllers/DetailSections.php b/application/controllers/DetailSections.php index 1aead75f..aee8eadc 100644 --- a/application/controllers/DetailSections.php +++ b/application/controllers/DetailSections.php @@ -3,30 +3,44 @@ namespace Icinga\Module\Vspheredb\Controllers; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\Html\HtmlString; trait DetailSections { - protected function section($content) + /** + * @param mixed $content + * + * @return ?HtmlElement + */ + protected function section(mixed $content): ?HtmlElement { $content = Html::wantHtml($content)->render(); - if (\strlen($content) === 0) { + if (strlen($content) === 0) { return null; } - return Html::tag('div', [ - 'class' => 'section', - ], new HtmlString($content)); + return Html::tag('div', ['class' => 'section'], new HtmlString($content)); } - protected function addSection($content) + /** + * @param mixed $content + * + * @return $this + */ + protected function addSection(mixed $content): static { $this->content()->add($this->section($content)); return $this; } - protected function addSections(array $sections) + /** + * @param array $sections + * + * @return $this + */ + protected function addSections(array $sections): static { foreach ($sections as $section) { $this->addSection($section); diff --git a/application/controllers/EventsController.php b/application/controllers/EventsController.php index e71a1929..4643327d 100644 --- a/application/controllers/EventsController.php +++ b/application/controllers/EventsController.php @@ -6,23 +6,23 @@ use gipfl\IcingaWeb2\Url; use gipfl\Web\Widget\Hint; use Icinga\Date\DateFormatter; +use Icinga\Module\Vspheredb\Web\Controller; use Icinga\Module\Vspheredb\Web\Form\FilterHostParentForm; use Icinga\Module\Vspheredb\Web\Table\EventHistoryTable; -use Icinga\Module\Vspheredb\Web\Controller; use Icinga\Module\Vspheredb\Web\Widget\CalendarForEvents; use Icinga\Module\Vspheredb\Web\Widget\VMotionHeatmap; use Ramsey\Uuid\Uuid; class EventsController extends Controller { - public function init() + public function init(): void { $this->assertPermission('vspheredb/admin'); parent::init(); $this->handleTabs(); } - public function indexAction() + public function indexAction(): void { $this->actions()->add(Link::create( $this->translate('Calendar'), @@ -30,7 +30,7 @@ public function indexAction() $this->url()->getParams()->toArray(false), [ 'class' => 'icon-calendar', - 'data-base-target' => '_main', + 'data-base-target' => '_main' ] )); @@ -62,7 +62,10 @@ public function indexAction() $table->renderTo($this); } - protected function addFilterForm() + /** + * @return FilterHostParentForm + */ + protected function addFilterForm(): FilterHostParentForm { $form = new FilterHostParentForm($this->db()); $form->handleRequest($this->getServerRequest()); @@ -71,7 +74,7 @@ protected function addFilterForm() return $form; } - public function heatmapAction() + public function heatmapAction(): void { $this->actions()->add(Link::create( $this->translate('Table'), @@ -79,7 +82,7 @@ public function heatmapAction() $this->url()->getParams()->toArray(false), [ 'class' => 'icon-th-list', - 'data-base-target' => '_main', + 'data-base-target' => '_main' ] )); @@ -97,7 +100,10 @@ public function heatmapAction() $this->content()->add(new CalendarForEvents($heatMap, $baseUrl, $form->getColors())); } - protected function handleTabs() + /** + * @return void + */ + protected function handleTabs(): void { $params = []; if ($day = $this->params->get('day')) { @@ -108,7 +114,7 @@ protected function handleTabs() } $tabs = $this->tabs()->add('events', [ 'label' => $this->translate('Events'), - 'url' => $this->url(), + 'url' => $this->url() ])->add('alarms', [ 'label' => $this->translate('Alarms'), 'url' => $alarmsUrl, diff --git a/application/controllers/HostController.php b/application/controllers/HostController.php index 040ffb6d..f18c3a81 100644 --- a/application/controllers/HostController.php +++ b/application/controllers/HostController.php @@ -9,6 +9,7 @@ use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\Web\Controller; +use Icinga\Module\Vspheredb\Web\Table\EventHistoryTable; use Icinga\Module\Vspheredb\Web\Table\HostHbaTable; use Icinga\Module\Vspheredb\Web\Table\HostPciDevicesTable; use Icinga\Module\Vspheredb\Web\Table\HostPhysicalNicTable; @@ -17,29 +18,28 @@ use Icinga\Module\Vspheredb\Web\Table\Object\HostSystemInfoTable; use Icinga\Module\Vspheredb\Web\Table\Object\HostVirtualizationInfoTable; use Icinga\Module\Vspheredb\Web\Table\Objects\VmsTable; -use Icinga\Module\Vspheredb\Web\Table\EventHistoryTable; use Icinga\Module\Vspheredb\Web\Widget\AdditionalTableActions; use Icinga\Module\Vspheredb\Web\Widget\CustomValueDetails; use Icinga\Module\Vspheredb\Web\Widget\HostHeader; use Icinga\Module\Vspheredb\Web\Widget\HostMonitoringInfo; use Icinga\Module\Vspheredb\Web\Widget\Summaries; use Icinga\Module\Vspheredb\Web\Widget\TaggingDetails; +use ipl\Html\Attributes; class HostController extends Controller { use DetailSections; use SingleObjectMonitoring; - /** @var HostHeader */ - protected $hostHeader; + protected ?HostHeader $hostHeader = null; /** * @throws MissingParameterException|NotFoundError */ - public function indexAction() + public function indexAction(): void { $host = $this->addHost(); - $this->content()->addAttributes(['class' => 'host-info']); + $this->content()->addAttributes(Attributes::create(['class' => 'host-info'])); $vCenter = VCenter::load($host->get('vcenter_uuid'), $host->getConnection()); $quickStats = HostQuickStats::loadFor($host); $this->addSections([ @@ -50,15 +50,14 @@ public function indexAction() new HostHardwareInfoTable($host, $quickStats), new HostMonitoringInfo($host), new HostPhysicalNicTable($host), - new HostHbaTable($host), + new HostHbaTable($host) ]); } /** * @throws MissingParameterException|NotFoundError - */ - public function vmsAction() + public function vmsAction(): void { $host = $this->addHost(); $table = new VmsTable($this->db(), $this->url()); @@ -72,9 +71,8 @@ public function vmsAction() /** * @throws MissingParameterException|NotFoundError - */ - public function sensorsAction() + public function sensorsAction(): void { $table = new HostSensorsTable($this->db()); $table->filterHost($this->addHost()); @@ -83,9 +81,8 @@ public function sensorsAction() /** * @throws MissingParameterException|NotFoundError - */ - public function pcidevicesAction() + public function pcidevicesAction(): void { $table = new HostPciDevicesTable($this->db()); $table->filterHost($this->addHost())->renderTo($this); @@ -93,30 +90,30 @@ public function pcidevicesAction() /** * @throws MissingParameterException|NotFoundError - */ - public function eventsAction() + public function eventsAction(): void { $table = new EventHistoryTable($this->db()); $table->filterHost($this->addHost())->renderTo($this); } - public function monitoringAction() + public function monitoringAction(): void { $this->showMonitoringDetails($this->addHost()); } /** * @return HostSystem + * * @throws MissingParameterException|NotFoundError */ - protected function addHost() + protected function addHost(): HostSystem { $host = HostSystem::loadWithUuid($this->params->getRequired('uuid'), $this->db()); $this->getRestrictionHelper()->assertAccessToVCenterUuidIsGranted($host->get('vcenter_uuid')); $quickStats = HostQuickStats::loadFor($host); $this->controls()->add($this->hostHeader = new HostHeader($host, $quickStats)); - $this->controls()->addAttributes(['class' => 'controls-with-object-header']); + $this->controls()->addAttributes(Attributes::create(['class' => 'controls-with-object-header'])); $this->setTitle($host->object()->get('object_name')); $this->handleTabs($host); @@ -125,9 +122,12 @@ protected function addHost() /** * @param HostSystem $host + * + * @return void + * * @throws MissingParameterException */ - protected function handleTabs(HostSystem $host) + protected function handleTabs(HostSystem $host): void { $hexId = $this->params->getRequired('uuid'); $this->tabs()->add('index', [ diff --git a/application/controllers/HostsController.php b/application/controllers/HostsController.php index 050d531a..69ce3618 100644 --- a/application/controllers/HostsController.php +++ b/application/controllers/HostsController.php @@ -3,15 +3,15 @@ namespace Icinga\Module\Vspheredb\Controllers; use Icinga\Authentication\Auth; -use Icinga\Module\Vspheredb\Web\OverviewTree; -use Icinga\Module\Vspheredb\Web\Widget\AdditionalTableActions; use Icinga\Module\Vspheredb\Web\Controller\ObjectsController; +use Icinga\Module\Vspheredb\Web\OverviewTree; use Icinga\Module\Vspheredb\Web\Table\Objects\HostsTable; +use Icinga\Module\Vspheredb\Web\Widget\AdditionalTableActions; use Icinga\Module\Vspheredb\Web\Widget\Summaries; class HostsController extends ObjectsController { - public function indexAction() + public function indexAction(): void { $this->handleTabs(); $this->addTreeViewToggle(); @@ -40,7 +40,7 @@ public function indexAction() $this->content()->prepend($summaries); } - public function exportAction() + public function exportAction(): void { $this->sendExport('host_system'); } diff --git a/application/controllers/MonitoringController.php b/application/controllers/MonitoringController.php index 21b3b9fd..a56ac0dc 100644 --- a/application/controllers/MonitoringController.php +++ b/application/controllers/MonitoringController.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Controllers; +use Exception; use gipfl\IcingaWeb2\Link; use gipfl\Web\Widget\Hint; use Icinga\Module\Vspheredb\DbObject\ManagedObject; @@ -21,21 +22,22 @@ use Icinga\Module\Vspheredb\Web\Table\TableWithVCenterFilter; use Icinga\Module\Vspheredb\Web\Widget\Documentation; use Icinga\Web\Notification; +use ipl\Html\Attributes; +use ipl\Html\Contract\Form; use ipl\Html\Html; use Ramsey\Uuid\Uuid; -use RuntimeException; class MonitoringController extends Controller { use AsyncControllerHelper; - protected $vCenterFilterForm; + protected ?FilterVCenterForm $vCenterFilterForm = null; - public function init() + public function init(): void { parent::init(); $action = $this->getRequest()->getActionName(); - if (preg_match('/tree$/', $action) || in_array($action, ['index', 'configuration', 'history'])) { + if (str_ends_with($action, 'tree') || in_array($action, ['index', 'configuration', 'history'])) { $tabs = $this->tabs(); $tabs->add('index', [ 'label' => $this->translate('Monitoring'), @@ -61,7 +63,7 @@ public function init() } $tabs->activate($action); } - if (preg_match('/tree$/', $action)) { + if (str_ends_with($action, 'tree')) { $this->actions()->add( Link::create($this->translate('Back to overview'), 'vspheredb/monitoring', null, [ 'class' => 'icon-left-small' @@ -74,7 +76,7 @@ public function init() } } - public function indexAction() + public function indexAction(): void { $this->addTitle($this->translate('Monitoring Rules')); $this->setAutorefreshInterval(20); @@ -83,7 +85,7 @@ public function indexAction() $table->renderTo($this); } - public function problemsAction() + public function problemsAction(): void { $this->addSingleTab($this->translate('Current Problems')); $vCenter = $this->requireVCenter(); @@ -97,7 +99,7 @@ public function problemsAction() $table->renderTo($this); } - public function historyAction() + public function historyAction(): void { $this->addTitle($this->translate('Monitoring Rules - Problem History')); $this->setAutorefreshInterval(20); @@ -106,13 +108,11 @@ public function historyAction() $table->renderTo($this); } - public function configurationAction() + public function configurationAction(): void { $this->assertPermission('vspheredb/admin'); $this->addTitle($this->translate('Monitoring Rules')); - $this->content()->addAttributes([ - 'class' => 'overview-chapter' - ]); + $this->content()->addAttributes(Attributes::create(['class' => 'overview-chapter'])); $this->content()->add([ Hint::info(Html::sprintf($this->translate( 'The Icinga vSphere%s Integration ships a lot of data, state and sensor values.' @@ -143,45 +143,55 @@ public function configurationAction() ]); } - public function hostrulesAction() + public function hostrulesAction(): void { $this->showType(ObjectType::HOST_SYSTEM); } - public function hosttreeAction() + public function hosttreeAction(): void { $this->showTree(ObjectType::HOST_SYSTEM); } - public function vmrulesAction() + public function vmrulesAction(): void { $this->showType(ObjectType::VIRTUAL_MACHINE); } - public function vmtreeAction() + public function vmtreeAction(): void { $this->showTree(ObjectType::VIRTUAL_MACHINE); } - public function datastorerulesAction() + public function datastorerulesAction(): void { $this->showType(ObjectType::DATASTORE); } - public function datastoretreeAction() + public function datastoretreeAction(): void { $this->showTree(ObjectType::DATASTORE); } - public function showTree($chosenType) + /** + * @param ObjectType $chosenType + * + * @return void + */ + public function showTree(ObjectType $chosenType): void { $this->assertPermission('vspheredb/admin'); $this->addTitle($this->translate('Monitoring')); - $tree = new MonitoringRulesTree($this->db(), $chosenType); - $this->content()->add(new MonitoringRulesTreeRenderer($tree, "vspheredb/monitoring/{$chosenType}rules")); + $tree = new MonitoringRulesTree($this->db(), $chosenType->value); + $this->content()->add(new MonitoringRulesTreeRenderer($tree, "vspheredb/monitoring/{$chosenType->value}rules")); } - public function showType($chosenType) + /** + * @param ObjectType $chosenType + * + * @return void + */ + public function showType(ObjectType $chosenType): void { $this->assertPermission('vspheredb/admin'); $this->addSingleTab($this->translate('Rules')); @@ -222,12 +232,12 @@ public function showType($chosenType) } } $this->addTitle($title); - $tree = new MonitoringRulesTree($db, $chosenType); - $storedConfig = MonitoringRuleSet::loadOptionalForUuid($binaryUuid, $chosenType, $db); + $tree = new MonitoringRulesTree($db, $chosenType->value); + $storedConfig = MonitoringRuleSet::loadOptionalForUuid($binaryUuid, $chosenType->value, $db); $inherited = InheritedSettings::loadFor($binaryUuid, $tree, $db); $inherited->setInternalDefaults(RuleSetRegistry::default()); $form = new RuleForm($chosenType, $binaryUuid, $db, $inherited, $storedConfig); - $form->on(RuleForm::ON_SUCCESS, function (RuleForm $form) use ($title) { + $form->on(Form::ON_SUBMIT, function (RuleForm $form) use ($title) { if ($form->hasNotBeenModified()) { Notification::info($this->translate('No change has been applied')); $this->redirectNow($this->url()); @@ -241,7 +251,7 @@ public function showType($chosenType) 'Current problems have NOT been recalculated, they will be applied with a short delay' )); } - } catch (\Exception $e) { + } catch (Exception $e) { Notification::info( $this->translate( 'Error when triggering problem recalculation, changes will be applied with a short delay' @@ -267,22 +277,28 @@ public function showType($chosenType) ]); } - protected function getTypeLabelForObjectType(string $type): string + /** + * @param ObjectType $type + * + * @return string + */ + protected function getTypeLabelForObjectType(ObjectType $type): string { - switch ($type) { - case 'host': - return $this->translate('Host Systems'); - case 'vm': - return $this->translate('Virtual Machines'); - case 'datastore': - return $this->translate('Datastores'); - } - - throw new RuntimeException("Unexpected object type: '$type'"); + return match ($type) { + ObjectType::HOST_SYSTEM => $this->translate('Host Systems'), + ObjectType::VIRTUAL_MACHINE => $this->translate('Virtual Machines'), + ObjectType::DATASTORE => $this->translate('Datastores') + }; } - // Duplicated from ObjectsController - protected function filterByVCenterIfRequired(TableWithVCenterFilter $table) + /** + * Duplicated from ObjectsController + * + * @param TableWithVCenterFilter $table + * + * @return void + */ + protected function filterByVCenterIfRequired(TableWithVCenterFilter $table): void { $this->getRestrictionHelper()->restrictTable($table); $this->controls()->prepend($this->getVCenterFilterForm()); @@ -292,7 +308,11 @@ protected function filterByVCenterIfRequired(TableWithVCenterFilter $table) } } - // Duplicated from ObjectsController + /** + * Duplicated from ObjectsController + * + * @return FilterVCenterForm + */ protected function getVCenterFilterForm(): FilterVCenterForm { if ($this->vCenterFilterForm === null) { diff --git a/application/controllers/OverviewController.php b/application/controllers/OverviewController.php index 3e883ee3..c43c2ae8 100644 --- a/application/controllers/OverviewController.php +++ b/application/controllers/OverviewController.php @@ -7,7 +7,7 @@ class OverviewController extends ObjectsController { - public function indexAction() + public function indexAction(): void { $type = $this->params->getRequired('type'); $this->activateTab($type) @@ -15,7 +15,12 @@ public function indexAction() ->content()->add(new OverviewTree($this->db(), $this->getRestrictionHelper(), $type)); } - protected function activateTab($name) + /** + * @param string $name + * + * @return $this + */ + protected function activateTab(string $name): static { $this->controls()->getTabs()->add('datastore', [ 'label' => $this->translate('Datastores'), diff --git a/application/controllers/PerfdataController.php b/application/controllers/PerfdataController.php index 8fe28a3f..b29d58f9 100644 --- a/application/controllers/PerfdataController.php +++ b/application/controllers/PerfdataController.php @@ -17,19 +17,19 @@ use Icinga\Module\Vspheredb\Web\Tabs\VCenterTabs; use Icinga\Module\Vspheredb\Web\Widget\AdditionalTableActions; use Icinga\Web\Notification; -use ipl\Html\Html; +use ipl\Html\Contract\Form; use Ramsey\Uuid\Uuid; class PerfdataController extends Controller { use AsyncControllerHelper; - public function init() + public function init(): void { $this->assertPermission('vspheredb/admin'); } - public function countersAction() + public function countersAction(): void { $vCenter = $this->requireVCenter(); $this->tabs(new VCenterTabs($vCenter))->activate('perfcounters'); @@ -47,14 +47,14 @@ public function countersAction() $table->renderTo($this); } - public function consumersAction() + public function consumersAction(): void { $this->setAutorefreshInterval(10); $this->tabs(new ConfigTabs())->activate('perfdata'); $this->addTitle($this->translate('Performance Data Consumers')); $this->actions()->add(Link::create($this->translate('Add'), 'vspheredb/perfdata/consumer', null, [ 'data-base-target' => '_next', - 'class' => 'icon-plus', + 'class' => 'icon-plus' ])); $table = new PerfDataConsumerTable($this->db()->getDbAdapter()); if (count($table) === 0) { @@ -64,20 +64,20 @@ public function consumersAction() $table->renderTo($this); } - public function consumerAction() + public function consumerAction(): void { $store = new ZfDbStore($this->db()->getDbAdapter()); $form = new PerfdataConsumerForm($this->loop(), $this->remoteClient(), $store); - $form->on($form::ON_DELETE, function () { + $form->on(PerfdataConsumerForm::ON_DELETE, function () { Notification::success($this->translate('Performance Data Consumer has been removed')); $this->redirectNow('vspheredb/perfdata/consumers'); }); - $form->on(PerfdataConsumerForm::ON_SUCCESS, function (PerfdataConsumerForm $form) { - if ($form->wasNew()) { - Notification::success($this->translate('Performance Data Consumer has been created')); - } else { - Notification::success($this->translate('Performance Data Consumer has been updated')); - } + $form->on(Form::ON_SUBMIT, function (PerfdataConsumerForm $form) { + Notification::success( + $form->wasNew() + ? $this->translate('Performance Data Consumer has been created') + : $this->translate('Performance Data Consumer has been updated') + ); $this->redirectNow(Url::fromPath('vspheredb/perfdata/consumer', [ 'uuid' => Uuid::fromBytes($form->getObject()->get('uuid'))->toString() ])); diff --git a/application/controllers/PhperrorController.php b/application/controllers/PhperrorController.php deleted file mode 100644 index be00199e..00000000 --- a/application/controllers/PhperrorController.php +++ /dev/null @@ -1,43 +0,0 @@ -getTabs()->add('error', [ - 'label' => $this->translate('Error'), - 'url' => $this->getRequest()->getUrl() - ])->activate('error'); - $requiredVersion = '7.1.x'; - $msg = $this->translate( - "PHP version %s is required for vSphereDB, you're running %s." - ); - $this->view->title = $this->translate('Unsatisfied dependencies'); - $this->view->message = sprintf($msg, $requiredVersion, PHP_VERSION); - } - - public function dependenciesAction() - { - $checker = new DependencyChecker(Icinga::app()); - if ($checker->satisfiesDependencies($this->Module())) { - $this->redirectNow('vspheredb/vcenters'); - } - $this->setAutorefreshInterval(15); - $this->getTabs()->add('error', [ - 'label' => $this->translate('Error'), - 'url' => $this->getRequest()->getUrl() - ])->activate('error'); - $this->view->title = $this->translate('Unsatisfied dependencies'); - $this->view->table = (new DependencyInfoTable($checker, $this->Module()))->render(); - $this->view->message = $this->translate( - "Icinga vSphereDb depends on the following modules, please install/upgrade as required" - ); - } -} diff --git a/application/controllers/PortgroupController.php b/application/controllers/PortgroupController.php index 67595816..d5e3c805 100644 --- a/application/controllers/PortgroupController.php +++ b/application/controllers/PortgroupController.php @@ -3,6 +3,8 @@ namespace Icinga\Module\Vspheredb\Controllers; use Icinga\Authentication\Auth; +use Icinga\Exception\MissingParameterException; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\DbObject\DistributedVirtualPortgroup; use Icinga\Module\Vspheredb\Web\Controller\ObjectsController; use Icinga\Module\Vspheredb\Web\Table\Objects\NetworkAdaptersTable; @@ -12,10 +14,10 @@ class PortgroupController extends ObjectsController { /** - * @throws \Icinga\Exception\MissingParameterException - * @throws \Icinga\Exception\NotFoundError + * @throws MissingParameterException + * @throws NotFoundError */ - public function indexAction() + public function indexAction(): void { $this->setAutorefreshInterval(15); $table = new NetworkAdaptersTable($this->db(), $this->url()); diff --git a/application/controllers/ResourcepoolsController.php b/application/controllers/ResourcepoolsController.php index 08e1fb1f..1f1a8876 100644 --- a/application/controllers/ResourcepoolsController.php +++ b/application/controllers/ResourcepoolsController.php @@ -10,7 +10,7 @@ class ResourcepoolsController extends ObjectsController { - public function indexAction() + public function indexAction(): void { $this->addSingleTab($this->translate('Resource Pools')); $table = new ResourcePoolsTable($this->db(), $this->url()); diff --git a/application/controllers/ResourcesController.php b/application/controllers/ResourcesController.php index d6b6e115..983e2fc8 100644 --- a/application/controllers/ResourcesController.php +++ b/application/controllers/ResourcesController.php @@ -4,6 +4,7 @@ use gipfl\IcingaWeb2\Link; use Icinga\Authentication\Auth; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\Web\Controller\ObjectsController; use Icinga\Module\Vspheredb\Web\Table\Objects\ComputeClusterHostSummaryTable; @@ -15,9 +16,9 @@ class ResourcesController extends ObjectsController { /** - * @throws \Icinga\Exception\NotFoundError + * @throws NotFoundError */ - public function clustersAction() + public function clustersAction(): void { if ($vCenterUuid = $this->params->get('vcenter')) { $vCenter = VCenter::loadWithUuid($vCenterUuid, $this->db()); @@ -47,9 +48,9 @@ public function clustersAction() } /** - * @throws \Icinga\Exception\NotFoundError + * @throws NotFoundError */ - public function hostsAction() + public function hostsAction(): void { $this->addSingleTab('Compute Resources'); @@ -73,7 +74,7 @@ public function hostsAction() $this->showTable($table, 'vspheredb/groupedvms'); } - public function projectsAction() + public function projectsAction(): void { $this->addSingleTab('Project Summary'); $this->setAutorefreshInterval(15); diff --git a/application/controllers/RpcServerUpdateHelper.php b/application/controllers/RpcServerUpdateHelper.php index 6afec32a..cb995783 100644 --- a/application/controllers/RpcServerUpdateHelper.php +++ b/application/controllers/RpcServerUpdateHelper.php @@ -2,26 +2,28 @@ namespace Icinga\Module\Vspheredb\Controllers; +use Exception; use Icinga\Module\Vspheredb\DbObject\VCenterServer; use Icinga\Module\Vspheredb\Polling\ServerSet; trait RpcServerUpdateHelper { - protected function sendServerInfoToSocket() + protected function sendServerInfoToSocket(): string { /** @var ConfigurationController $this */ try { $connection = $this->db(); if ( - $this->syncRpcCall('vsphere.setServers', [ - 'servers' => ServerSet::fromServers(VCenterServer::loadEnabledServers($connection)) - ]) + $this->syncRpcCall( + 'vsphere.setServers', + ['servers' => ServerSet::fromServers(VCenterServer::loadEnabledServers($connection))] + ) ) { return $this->translate('Daemon configuration has been refreshed'); - } else { - return $this->translate('Daemon configuration has NOT been refreshed'); } - } catch (\Exception $e) { + + return $this->translate('Daemon configuration has NOT been refreshed'); + } catch (Exception $e) { return $this->translate('Daemon configuration refresh FAILED: ' . $e->getMessage()); } } diff --git a/application/controllers/SingleObjectMonitoring.php b/application/controllers/SingleObjectMonitoring.php index 75a75f0d..193861cc 100644 --- a/application/controllers/SingleObjectMonitoring.php +++ b/application/controllers/SingleObjectMonitoring.php @@ -6,6 +6,7 @@ use gipfl\Web\Widget\Hint; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use Icinga\Module\Vspheredb\Monitoring\CheckRunner; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Web\Table\Monitoring\MonitoringRuleProblemHistoryTable; use Icinga\Module\Vspheredb\Web\Widget\CheckPluginHelper; use ipl\Html\Html; @@ -13,7 +14,12 @@ trait SingleObjectMonitoring { - protected function showMonitoringDetails(BaseDbObject $object) + /** + * @param BaseDbObject $object + * + * @return void + */ + protected function showMonitoringDetails(BaseDbObject $object): void { $history = $this->params->get('history'); if ($history) { @@ -37,7 +43,12 @@ protected function showMonitoringDetails(BaseDbObject $object) } } - protected function showMonitoringHistory(BaseDbObject $object) + /** + * @param BaseDbObject $object + * + * @return void + */ + protected function showMonitoringHistory(BaseDbObject $object): void { $this->setAutorefreshInterval(20); $table = new MonitoringRuleProblemHistoryTable($this->db()->getDbAdapter()); @@ -46,21 +57,20 @@ protected function showMonitoringHistory(BaseDbObject $object) $table->renderTo($this); } - protected function showRuleConfigurationHint(BaseDbObject $object) + /** + * @param BaseDbObject $object + * + * @return void + */ + protected function showRuleConfigurationHint(BaseDbObject $object): void { - switch ($object->getTableName()) { - case 'virtual_machine': - $tab = 'vmtree'; - break; - case 'host_system': - $tab = 'hosttree'; - break; - case 'datastore': - $tab = 'datastoretree'; - break; - default: - $tab = null; - } + $tab = match ($object->getTableName()) { + 'virtual_machine' => 'vmtree', + 'host_system' => 'hosttree', + 'datastore' => 'datastoretree', + default => null, + }; + if ($tab) { $this->content()->add(Html::tag('p', [Html::tag('br'), Html::sprintf( $this->translate('Please click %s to configure related Monitoring Rules'), @@ -69,6 +79,12 @@ protected function showRuleConfigurationHint(BaseDbObject $object) } } + /** + * @param BaseDbObject $object + * @param ?bool $inspect + * + * @return Hint + */ protected function createMonitoringHint(BaseDbObject $object, ?bool $inspect = null): Hint { return Hint::info(Html::sprintf( @@ -81,13 +97,18 @@ protected function createMonitoringHint(BaseDbObject $object, ?bool $inspect = n 'class' => 'logOutput' ], sprintf( 'icingacli vspheredb check %s --uuid %s%s', - CheckRunner::getCheckTypeForObject($object), + ObjectType::fromDbObject($object)->value, Uuid::fromBytes($object->get('uuid'))->toString(), $inspect ? ' --inspect' : '' )) )); } + /** + * @param ?bool $inspect + * + * @return Link + */ protected function createMonitoringInspectionLink(?bool $inspect = null): Link { if ($inspect) { @@ -97,16 +118,21 @@ protected function createMonitoringInspectionLink(?bool $inspect = null): Link null, ['class' => 'icon-left-big'] ); - } else { - return Link::create( - $this->translate('Inspect'), - $this->url()->with('inspect', true), - null, - ['class' => 'icon-services'] - ); } + + return Link::create( + $this->translate('Inspect'), + $this->url()->with('inspect', true), + null, + ['class' => 'icon-services'] + ); } + /** + * @param ?bool $inspect + * + * @return Link + */ protected function createMonitoringHistoryLink(?bool $inspect = null): Link { if ($inspect) { @@ -116,13 +142,13 @@ protected function createMonitoringHistoryLink(?bool $inspect = null): Link null, ['class' => 'icon-left-big'] ); - } else { - return Link::create( - $this->translate('Show history'), - $this->url()->with('history', true), - null, - ['class' => 'icon-history'] - ); } + + return Link::create( + $this->translate('Show history'), + $this->url()->with('history', true), + null, + ['class' => 'icon-history'] + ); } } diff --git a/application/controllers/StoragepodsController.php b/application/controllers/StoragepodsController.php index a09ccfcf..7cf003fa 100644 --- a/application/controllers/StoragepodsController.php +++ b/application/controllers/StoragepodsController.php @@ -10,7 +10,7 @@ class StoragepodsController extends ObjectsController { - public function indexAction() + public function indexAction(): void { $this->addSingleTab($this->translate('Storage Pods')); $this->setAutorefreshInterval(15); diff --git a/application/controllers/SwitchController.php b/application/controllers/SwitchController.php index 50693960..65d8df70 100644 --- a/application/controllers/SwitchController.php +++ b/application/controllers/SwitchController.php @@ -3,6 +3,8 @@ namespace Icinga\Module\Vspheredb\Controllers; use Icinga\Authentication\Auth; +use Icinga\Exception\MissingParameterException; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\DbObject\DistributedVirtualSwitch; use Icinga\Module\Vspheredb\Web\Controller\ObjectsController; use Icinga\Module\Vspheredb\Web\Table\Objects\PortGroupsTable; @@ -12,10 +14,10 @@ class SwitchController extends ObjectsController { /** - * @throws \Icinga\Exception\MissingParameterException - * @throws \Icinga\Exception\NotFoundError + * @throws MissingParameterException + * @throws NotFoundError */ - public function indexAction() + public function indexAction(): void { $this->setAutorefreshInterval(15); $table = new PortGroupsTable($this->db(), $this->url()); diff --git a/application/controllers/SwitchesController.php b/application/controllers/SwitchesController.php index 2d26146b..dc7fa042 100644 --- a/application/controllers/SwitchesController.php +++ b/application/controllers/SwitchesController.php @@ -10,7 +10,7 @@ class SwitchesController extends ObjectsController { - public function indexAction() + public function indexAction(): void { $this->addSingleTab($this->translate('Switches')); $this->setAutorefreshInterval(15); diff --git a/application/controllers/TopController.php b/application/controllers/TopController.php index 0058d8f9..adb250f0 100644 --- a/application/controllers/TopController.php +++ b/application/controllers/TopController.php @@ -4,15 +4,16 @@ use Icinga\Module\Vspheredb\Web\Controller; use Icinga\Module\Vspheredb\Web\Table\TopPerfTable; +use Zend_Db_Select; class TopController extends Controller { - public function init() + public function init(): void { $this->assertPermission('vspheredb/admin'); } - public function vmsAction() + public function vmsAction(): void { $this->setAutorefreshInterval(10); $parentId = $this->params->get('parent_uuid'); @@ -46,11 +47,11 @@ public function vmsAction() $this->fetchTop(543, $parentId), 'formatMicroSeconds', 'createVmLink' - ), + ) ]); } - public function foldersAction() + public function foldersAction(): void { $this->makeTabs(); $this->content()->add([ @@ -89,11 +90,17 @@ public function foldersAction() $this->fetchTopPerParent(543, 'AVG'), 'formatMicroSeconds', 'createTopForParentLink' - ), + ) ]); } - protected function fetchTop($counterUuid, $parentUuid = null) + /** + * @param int $counterUuid + * @param $parentUuid + * + * @return ?array + */ + protected function fetchTop(int $counterUuid, $parentUuid = null): ?array { $query = $this->fetchTopQuery($counterUuid); if ($parentUuid !== null) { @@ -102,7 +109,13 @@ protected function fetchTop($counterUuid, $parentUuid = null) return $this->db()->getDbAdapter()->fetchAll($query); } - protected function fetchTopPerParent($counterUuid, $agg) + /** + * @param int $counterUuid + * @param string $agg + * + * @return ?array + */ + protected function fetchTopPerParent(int $counterUuid, string $agg): ?array { $db = $this->db()->getDbAdapter(); $query = $db->select()->from( @@ -112,23 +125,23 @@ protected function fetchTopPerParent($counterUuid, $agg) 'value_minus1' => "$agg(c.value_minus1)", 'value_minus2' => "$agg(c.value_minus2)", 'value_minus3' => "$agg(c.value_minus3)", - 'value_minus4' => "$agg(c.value_minus4)", + 'value_minus4' => "$agg(c.value_minus4)" ] )->join( ['o' => 'object'], 'o.uuid = c.object_uuid', [ 'o.uuid', - 'o.overall_status', + 'o.overall_status' ] )->join( ['p' => 'object'], 'o.parent_uuid = p.uuid', [ 'object_uuid' => 'p.uuid', - 'object_name' => 'p.object_name', + 'object_name' => 'p.object_name' ] - )->where('counter_key = ?', (int) $counterUuid) + )->where('counter_key = ?', $counterUuid) ->group('p.uuid') ->order('value_last DESC') ->limit($this->params->get('limit', 10)); @@ -136,7 +149,12 @@ protected function fetchTopPerParent($counterUuid, $agg) return $db->fetchAll($query); } - protected function fetchTopQuery($counterId) + /** + * @param int $counterId + * + * @return Zend_Db_Select + */ + protected function fetchTopQuery(int $counterId): Zend_Db_Select { return $this->db()->getDbAdapter()->select()->from( ['c' => 'counter_300x5'], @@ -148,7 +166,7 @@ protected function fetchTopQuery($counterId) 'c.value_minus1', 'c.value_minus2', 'c.value_minus3', - 'c.value_minus4', + 'c.value_minus4' ] )->join( ['o' => 'object'], @@ -156,19 +174,30 @@ protected function fetchTopQuery($counterId) [ 'o.uuid', 'object_name' => 'o.object_name', - 'o.overall_status', + 'o.overall_status' ] - )->where('counter_key = ?', (int) $counterId) + )->where('counter_key = ?', $counterId) ->order('value_last DESC') ->limit($this->params->get('limit', 10)); } - protected function makeTopTable($title, $rows, $format, $link) + /** + * @param string $title + * @param ?array $rows + * @param ?string $format + * @param string $link + * + * @return TopPerfTable + */ + protected function makeTopTable(string $title, ?array $rows, ?string $format, string $link): TopPerfTable { return new TopPerfTable($title, $rows, $format, $link); } - protected function makeTabs() + /** + * @return void + */ + protected function makeTabs(): void { $this->tabs()->add('vms', [ 'label' => 'Top VMs', diff --git a/application/controllers/VcenterController.php b/application/controllers/VcenterController.php index 1241dbc0..1c4e53d6 100644 --- a/application/controllers/VcenterController.php +++ b/application/controllers/VcenterController.php @@ -20,7 +20,9 @@ use Icinga\Module\Vspheredb\Web\Widget\UsageSummary; use Icinga\Module\Vspheredb\Web\Widget\VCenterHeader; use Icinga\Module\Vspheredb\Web\Widget\VCenterSummaries; +use Icinga\Security\SecurityException; use Icinga\Web\Notification; +use ipl\Html\Contract\Form; use Ramsey\Uuid\Uuid; class VcenterController extends Controller @@ -28,7 +30,7 @@ class VcenterController extends Controller use AsyncControllerHelper; use RpcServerUpdateHelper; - public function indexAction() + public function indexAction(): void { $vCenter = $this->requireVCenter(); $this->tabs(new VCenterTabs($vCenter))->activate('vcenter'); @@ -53,7 +55,7 @@ public function indexAction() $this->content()->add(new VCenterSummaries($vCenter)); } - public function editAction() + public function editAction(): void { $this->assertPermission('vspheredb/admin'); $vCenter = $this->requireVCenter(); @@ -75,7 +77,7 @@ public function editAction() }; $form = new VCenterForm($vCenter); - $form->on(VCenterForm::ON_SUCCESS, $success); + $form->on(Form::ON_SUBMIT, $success); $form->handleRequest($this->getServerRequest()); $this->content()->add($form); @@ -84,7 +86,7 @@ public function editAction() if ($subscription = PerfdataSubscription::optionallyLoadForVCenter($vCenter, $store)) { $form->setObject($subscription); } - $form->on(VCenterShipMetricsForm::ON_SUCCESS, function () { + $form->on(Form::ON_SUBMIT, function () { $this->redirectNow($this->getOriginalUrl()); }); $form->on(VCenterShipMetricsForm::ON_DELETE, function () { @@ -94,7 +96,7 @@ public function editAction() $this->content()->add($form); $form = new DeleteVCenterForm($this->db(), $vCenter, $this->remoteClient(), $this->loop()); - $form->on(DeleteVCenterForm::ON_SUCCESS, function () use ($vCenter) { + $form->on(Form::ON_SUBMIT, function () use ($vCenter) { $this->redirectNow('vspheredb/vcenters'); }); $form->handleRequest($this->getServerRequest()); @@ -102,9 +104,9 @@ public function editAction() } /** - * @throws \Icinga\Security\SecurityException + * @throws SecurityException */ - public function serverAction() + public function serverAction(): void { $this->assertPermission('vspheredb/admin'); $this->addSingleTab($this->translate('vCenter Server')); @@ -116,14 +118,12 @@ public function serverAction() $this->addTitle($this->translate('Create a new vCenter/ESXi-Connection')); } - $form->on(VCenterServerForm::ON_SUCCESS, function (VCenterServerForm $form) { + $form->on(Form::ON_SUBMIT, function (VCenterServerForm $form) { $object = $form->getObject(); if ($object->hasBeenModified()) { - $msg = sprintf( - $object->hasBeenLoadedFromDb() - ? $this->translate('The Connection has successfully been stored') - : $this->translate('A new Connection has successfully been created') - ); + $msg = $object->hasBeenLoadedFromDb() + ? $this->translate('The Connection has successfully been stored') + : $this->translate('A new Connection has successfully been created'); $object->store(); $msg .= '. ' . $this->sendServerInfoToSocket(); } else { @@ -140,7 +140,10 @@ public function serverAction() } } - protected function handleTabs() + /** + * @return void + */ + protected function handleTabs(): void { $action = $this->getRequest()->getActionName(); $tabs = $this->tabs(new MainTabs($this->Auth(), $this->db())); diff --git a/application/controllers/VcentersController.php b/application/controllers/VcentersController.php index 560b83e7..ad55dc97 100644 --- a/application/controllers/VcentersController.php +++ b/application/controllers/VcentersController.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Controllers; +use Exception; use gipfl\IcingaWeb2\Link; use gipfl\Web\Widget\Hint; use Icinga\Authentication\Auth; @@ -16,16 +17,20 @@ use Icinga\Module\Vspheredb\Web\Widget\UsageSummary; use Icinga\Module\Vspheredb\WebUtil; use ipl\Html\Html; +use Zend_Db_Select_Exception; class VcentersController extends ObjectsController { use AsyncControllerHelper; - protected function getConnectionsByVCenter() + /** + * @return ?array + */ + protected function getConnectionsByVCenter(): ?array { try { $connections = $this->syncRpcCall('vsphere.getApiConnections'); - } catch (\Exception $e) { + } catch (Exception) { return null; } $connectionState = new ConnectionState($connections, $this->db()->getDbAdapter()); @@ -33,9 +38,9 @@ protected function getConnectionsByVCenter() } /** - * @throws \Zend_Db_Select_Exception + * @throws Zend_Db_Select_Exception */ - public function indexAction() + public function indexAction(): void { $this->setAutorefreshInterval(15); $this->addSingleTab($this->translate('VCenters')); @@ -79,7 +84,10 @@ public function indexAction() // $this->controls()->prepend($this->cpuSummary($table)); } - protected function addNoVCenterHint() + /** + * @return void + */ + protected function addNoVCenterHint(): void { $this->content()->add(Hint::warning( $this->translate('No vCenter available. You might want to check your %s or your %s'), @@ -96,10 +104,12 @@ protected function addNoVCenterHint() /** * @param VCenterSummaryTable $table + * * @return CpuAbsoluteUsage - * @throws \Zend_Db_Select_Exception + * + * @throws Zend_Db_Select_Exception */ - protected function cpuSummary(VCenterSummaryTable $table) + protected function cpuSummary(VCenterSummaryTable $table): CpuAbsoluteUsage { $query = clone($table->getQuery()); $query->reset('columns')->reset('limitcount')->reset('limitoffset')->reset('group'); @@ -107,7 +117,7 @@ protected function cpuSummary(VCenterSummaryTable $table) 'used_mhz' => 'SUM(hqs.overall_cpu_usage)', 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)', 'used_mb' => 'SUM(hqs.overall_memory_usage_mb)', - 'total_mb' => 'SUM(h.hardware_memory_size_mb)', + 'total_mb' => 'SUM(h.hardware_memory_size_mb)' ]); $total = $this->db()->getDbAdapter()->fetchRow($query); @@ -117,7 +127,10 @@ protected function cpuSummary(VCenterSummaryTable $table) ); } - protected function handleTabs() + /** + * @return void + */ + protected function handleTabs(): void { $action = $this->getRequest()->getControllerName(); $tabs = $this->tabs(new MainTabs($this->Auth(), $this->db())); @@ -128,7 +141,10 @@ protected function handleTabs() } } - protected function checkDaemonStatus() + /** + * @return void + */ + protected function checkDaemonStatus(): void { $db = $this->db()->getDbAdapter(); $daemon = $db->fetchRow( @@ -152,7 +168,10 @@ protected function checkDaemonStatus() } } - protected function checkForMigrations() + /** + * @return void + */ + protected function checkForMigrations(): void { if (Db::migrationsForDb($this->db())->hasPendingMigrations()) { $this->redirectNow('vspheredb/configuration/database'); diff --git a/application/controllers/VmController.php b/application/controllers/VmController.php index 730b7d7e..ec2d7830 100644 --- a/application/controllers/VmController.php +++ b/application/controllers/VmController.php @@ -9,6 +9,7 @@ use Icinga\Module\Vspheredb\DbObject\VmQuickStats; use Icinga\Module\Vspheredb\Web\Controller; use Icinga\Module\Vspheredb\Web\Table\AlarmHistoryTable; +use Icinga\Module\Vspheredb\Web\Table\EventHistoryTable; use Icinga\Module\Vspheredb\Web\Table\Object\VmEssentialInfoTable; use Icinga\Module\Vspheredb\Web\Table\Object\VmExtraInfoTable; use Icinga\Module\Vspheredb\Web\Table\Object\VmLocationInfoTable; @@ -16,7 +17,6 @@ use Icinga\Module\Vspheredb\Web\Table\VmDisksTable; use Icinga\Module\Vspheredb\Web\Table\VmDiskUsageTable; use Icinga\Module\Vspheredb\Web\Table\VmNetworkAdapterTable; -use Icinga\Module\Vspheredb\Web\Table\EventHistoryTable; use Icinga\Module\Vspheredb\Web\Table\VmSnapshotTable; use Icinga\Module\Vspheredb\Web\Widget\CustomValueDetails; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; @@ -25,6 +25,7 @@ use Icinga\Module\Vspheredb\Web\Widget\VmHardwareTree; use Icinga\Module\Vspheredb\Web\Widget\VmHeader; use Icinga\Module\Vspheredb\Web\Widget\VmRouteConfigTable; +use ipl\Html\Attributes; class VmController extends Controller { @@ -35,12 +36,10 @@ class VmController extends Controller * @throws MissingParameterException * @throws NotFoundError */ - public function indexAction() + public function indexAction(): void { $vm = $this->addVm(); - $this->content()->addAttributes([ - 'class' => 'vm-info' - ]); + $this->content()->addAttributes(Attributes::create(['class' => 'vm-info'])); $vCenter = VCenter::load($vm->get('vcenter_uuid'), $vm->getConnection()); $this->addSections([ new VmEssentialInfoTable($vm), @@ -54,26 +53,26 @@ public function indexAction() new VmDiskUsageTable($vm), new VmSnapshotTable($vm), new BackupToolInfo($vm), - new VmExtraInfoTable($vm), + new VmExtraInfoTable($vm) ]); } /** * @throws MissingParameterException|NotFoundError */ - public function hardwareAction() + public function hardwareAction(): void { $vm = $this->addVm(); $this->content()->add([ new SubTitle($this->translate('Hardware'), 'print'), - new VmHardwareTree($vm), + new VmHardwareTree($vm) ]); } /** * @throws MissingParameterException|NotFoundError */ - public function eventsAction() + public function eventsAction(): void { $table = new EventHistoryTable($this->db()); $table->filterVm($this->addVm())->renderTo($this); @@ -82,35 +81,39 @@ public function eventsAction() /** * @throws MissingParameterException|NotFoundError */ - public function alarmsAction() + public function alarmsAction(): void { $table = new AlarmHistoryTable($this->db()); $table->filterEntityUuid($this->addVm()->get('uuid'))->renderTo($this); } - public function monitoringAction() + public function monitoringAction(): void { $this->showMonitoringDetails($this->addVm()); } /** * @return VirtualMachine + * * @throws MissingParameterException * @throws NotFoundError */ - protected function addVm() + protected function addVm(): VirtualMachine { $vm = VirtualMachine::loadWithUuid($this->params->getRequired('uuid'), $this->db()); $this->getRestrictionHelper()->assertAccessToVCenterUuidIsGranted($vm->get('vcenter_uuid')); $this->controls()->add(new VmHeader($vm, VmQuickStats::loadFor($vm))); - $this->controls()->addAttributes(['class' => 'controls-with-object-header']); + $this->controls()->addAttributes(Attributes::create(['class' => 'controls-with-object-header'])); $this->setTitle($vm->object()->get('object_name')); $this->handleTabs(); return $vm; } - protected function handleTabs() + /** + * @return void + */ + protected function handleTabs(): void { $params = ['uuid' => $this->params->get('uuid')]; $this->tabs()->add('index', [ diff --git a/application/controllers/VmsController.php b/application/controllers/VmsController.php index c22845a4..cf53cb7f 100644 --- a/application/controllers/VmsController.php +++ b/application/controllers/VmsController.php @@ -14,12 +14,12 @@ class VmsController extends ObjectsController { - protected $otherTabActions = [ + protected array $otherTabActions = [ 'diskusage' => 'index', - 'snapshot' => 'index', + 'snapshot' => 'index' ]; - public function indexAction() + public function indexAction(): void { $this->handleTabs(); $this->addTreeViewToggle(); @@ -43,7 +43,7 @@ public function indexAction() 'vspheredb/vms/snapshot', $urlParams, ['class' => 'icon-database'] - ), + ) ]); $this->setAutorefreshInterval(15); @@ -59,12 +59,12 @@ public function indexAction() $this->content()->prepend($summaries); } - public function exportAction() + public function exportAction(): void { $this->sendExport('virtual_machine'); } - public function diskusageAction() + public function diskusageAction(): void { $this->handleTabs(); @@ -81,7 +81,7 @@ public function diskusageAction() 'vspheredb/vms/snapshot', $urlParams, ['class' => 'icon-database'] - ), + ) ]); $table = new VmsGuestDiskUsageTable($this->db(), $this->url()); (new AdditionalTableActions($table, Auth::getInstance(), $this->url())) @@ -89,7 +89,7 @@ public function diskusageAction() $this->showTable($table, 'vspheredb/vms', $this->translate('Virtual Machine Guest Disks')); } - public function snapshotAction() + public function snapshotAction(): void { $this->handleTabs(); $urlParams = $this->getParentParamsToPreserve(); @@ -105,7 +105,7 @@ public function snapshotAction() 'vspheredb/vms', $urlParams, ['class' => 'icon-left-small'] - ), + ) ]); $table = new VmsSnapshotsTable($this->db(), $this->url()); (new AdditionalTableActions($table, Auth::getInstance(), $this->url())) diff --git a/library/Vspheredb/Addon/BackupTool.php b/library/Vspheredb/Addon/BackupTool.php index f2d419da..e040167c 100644 --- a/library/Vspheredb/Addon/BackupTool.php +++ b/library/Vspheredb/Addon/BackupTool.php @@ -2,9 +2,8 @@ namespace Icinga\Module\Vspheredb\Addon; -use Icinga\Module\Vspheredb\DbObject\CustomValues; -use ipl\Html\HtmlDocument; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; +use ipl\Html\HtmlDocument; /** * Interface BackupTool @@ -20,21 +19,24 @@ interface BackupTool /** * @return string */ - public function getName(); + public function getName(): string; /** * @param VirtualMachine $vm + * * @return bool */ - public function wants(VirtualMachine $vm); + public function wants(VirtualMachine $vm): bool; /** * @param VirtualMachine $vm + * + * @return void */ - public function handle(VirtualMachine $vm); + public function handle(VirtualMachine $vm): void; /** - * @return HtmlDocument|null + * @return ?HtmlDocument */ - public function getInfoRenderer(); + public function getInfoRenderer(): ?HtmlDocument; } diff --git a/library/Vspheredb/Addon/IbmSpectrumProtect.php b/library/Vspheredb/Addon/IbmSpectrumProtect.php index 6481c1e3..a1d6ea8b 100644 --- a/library/Vspheredb/Addon/IbmSpectrumProtect.php +++ b/library/Vspheredb/Addon/IbmSpectrumProtect.php @@ -12,26 +12,32 @@ class IbmSpectrumProtect implements BackupTool public const CLOSE_TAG = ''; - protected $lastAttributes; + protected ?array $lastAttributes = null; - public function getName() + /** + * @return string + */ + public function getName(): string { return 'IBM Spectrum Protect'; } /** * @param VirtualMachine $vm + * * @return bool */ - public function wants(VirtualMachine $vm) + public function wants(VirtualMachine $vm): bool { return $this->wantsAnnotation($vm->get('annotation')); } /** * @param VirtualMachine $vm + * + * @return void */ - public function handle(VirtualMachine $vm) + public function handle(VirtualMachine $vm): void { $this->parseAnnotation($vm->get('annotation')); } @@ -39,24 +45,25 @@ public function handle(VirtualMachine $vm) /** * @return IbmSpectrumProtectBackupRunDetails */ - public function getInfoRenderer() + public function getInfoRenderer(): IbmSpectrumProtectBackupRunDetails { return new IbmSpectrumProtectBackupRunDetails($this); } /** * @param $annotation + * * @return bool */ - public function wantsAnnotation($annotation) + public function wantsAnnotation($annotation): bool { - return $annotation !== null && strpos($annotation, static::OPEN_TAG) !== false; + return $annotation !== null && str_contains($annotation, static::OPEN_TAG); } /** * @return array */ - public function requireParsedAttributes() + public function requireParsedAttributes(): array { $attributes = $this->getAttributes(); if ($attributes === null) { @@ -67,14 +74,19 @@ public function requireParsedAttributes() } /** - * @return array|null + * @return ?array */ - public function getAttributes() + public function getAttributes(): ?array { return $this->lastAttributes; } - protected function parseAnnotation($annotation) + /** + * @param string $annotation + * + * @return void + */ + protected function parseAnnotation(string $annotation): void { $beginPos = strpos($annotation, static::OPEN_TAG); if ($beginPos === false) { @@ -104,25 +116,27 @@ protected function parseAnnotation($annotation) ]; foreach ($lines as $line) { - if (strpos($line, '=') === false) { + if (! str_contains($line, '=')) { continue; } - [$key, $value] = preg_split('/=/', $line, 2); - if ($key === 'Last Run Time') { - $attributes[$key] = static::parseTime($value); - } elseif ($key === 'Data Transmitted') { - $attributes[$key] = static::parseBytes($value); - } elseif ($key === 'Duration') { - $attributes[$key] = static::parseDuration($value); - } else { - $attributes[$key] = static::parseString($value); - } + [$key, $value] = explode('=', $line, 2); + $attributes[$key] = match ($key) { + 'Last Run Time' => static::parseTime($value), + 'Data Transmitted' => static::parseBytes($value), + 'Duration' => static::parseDuration($value), + default => static::parseString($value) + }; } $this->lastAttributes = $attributes; } - public function stripAnnotation(&$annotation) + /** + * @param string $annotation + * + * @return void + */ + public function stripAnnotation(string &$annotation): void { $beginPos = strpos($annotation, static::OPEN_TAG); if ($beginPos === false) { @@ -131,15 +145,15 @@ public function stripAnnotation(&$annotation) $begin = $beginPos + strlen(static::OPEN_TAG) + 1; $end = strpos($annotation, static::CLOSE_TAG, $begin); - $annotation = substr($annotation, 0, $beginPos) - . substr($annotation, $end + strlen(static::CLOSE_TAG)); + $annotation = substr($annotation, 0, $beginPos) . substr($annotation, $end + strlen(static::CLOSE_TAG)); } /** - * @param $string - * @return string|null + * @param string $string + * + * @return ?string */ - public static function parseString($string) + public static function parseString(string $string): ?string { if (strlen($string) < 2) { return $string; @@ -147,30 +161,32 @@ public static function parseString($string) if (preg_match("/^'(.*)'$/", $string, $match)) { return $match[1]; - } else { - // Be strict. Otherwise we could of course return $string. - return null; } + + // Be strict. Otherwise we could of course return $string. + return null; } - public static function parseDuration($value) + /** + * @param string $value + * + * @return float|int|null + */ + public static function parseDuration(string $value): float|int|null { - if ( - preg_match( - '/^(\d{2}):(\d{2}):(\d{2})$/', - static::parseString($value), - $match - ) - ) { - return intval($match[1]) * 3600 - + intval($match[2]) * 60 - + intval($match[3]); - } else { - return null; + if (preg_match('/^(\d{2}):(\d{2}):(\d{2})$/', static::parseString($value), $match)) { + return intval($match[1]) * 3600 + intval($match[2]) * 60 + intval($match[3]); } + + return null; } - public static function parseBytes($value) + /** + * @param string $value + * + * @return ?int + */ + public static function parseBytes(string $value): ?int { $value = static::parseString($value); if ($value === null) { @@ -182,21 +198,22 @@ public static function parseBytes($value) 'KB' => 1024, 'MB' => 1024 * 1024, 'GB' => 1024 * 1024 * 1024, - 'TB' => 1024 * 1024 * 1024 * 1024, + 'TB' => 1024 * 1024 * 1024 * 1024 ]; if (preg_match('/^([0-9\.]+)\s+(B|KB|MB|GB|TB)$/', $value, $match)) { return (int) (sscanf($match[1], '%f')[0] * $byteMultipliers[$match[2]]); - } else { - return null; } + + return null; } /** * @param $time - * @return int|null + * + * @return ?int */ - public static function parseTime($time) + public static function parseTime($time): ?int { $time = strtotime(static::parseString($time)); if ($time === false) { diff --git a/library/Vspheredb/Addon/NetBackup.php b/library/Vspheredb/Addon/NetBackup.php index 58dff676..7c666201 100644 --- a/library/Vspheredb/Addon/NetBackup.php +++ b/library/Vspheredb/Addon/NetBackup.php @@ -14,12 +14,16 @@ class NetBackup extends SimpleBackupTool public const CV_EXCLUDE = 'NB_EXCLUDE_FROM_BACKUP'; - protected $customValues = [ + /** @var string[] */ + protected array $customValues = [ self::CV_LAST_BACKUP, self::CV_EXCLUDE ]; - public function getName() + /** + * @return string + */ + public function getName(): string { return 'Veritas NetBackup'; } @@ -27,12 +31,17 @@ public function getName() /** * @return NetBackupRunDetails */ - public function getInfoRenderer() + public function getInfoRenderer(): NetBackupRunDetails { return new NetBackupRunDetails($this); } - protected function parseCustomValues(CustomValues $values) + /** + * @param CustomValues $values + * + * @return void + */ + protected function parseCustomValues(CustomValues $values): void { if ($values->has(self::CV_LAST_BACKUP)) { $this->parseLastBackup($values->get(self::CV_LAST_BACKUP)); @@ -42,10 +51,15 @@ protected function parseCustomValues(CustomValues $values) } } - protected function parseLastBackup($string) + /** + * @param string $string + * + * @return void + */ + protected function parseLastBackup(string $string): void { // Sun Sep 13 00:27:42 2020 +0200,backuphost.name,jobname - $parts = \explode(',', $string); + $parts = explode(',', $string); $attributes = []; if (count($parts) === 3) { $attributes['Time'] = strtotime($parts[0]); diff --git a/library/Vspheredb/Addon/SimpleBackupTool.php b/library/Vspheredb/Addon/SimpleBackupTool.php index 7eb5eabb..eb7c4196 100644 --- a/library/Vspheredb/Addon/SimpleBackupTool.php +++ b/library/Vspheredb/Addon/SimpleBackupTool.php @@ -10,9 +10,13 @@ abstract class SimpleBackupTool implements BackupTool { public const PREFIX = 'no-such-prefix'; - protected $lastAttributes; + /** + * @var ?array + */ + protected ?array $lastAttributes = null; - protected $customValues = []; + /** @var string[] */ + protected array $customValues = []; /** * @return string[] @@ -24,17 +28,20 @@ protected function getCustomValues(): array /** * @param $annotation + * * @return bool */ - public function wantsAnnotation($annotation) + public function wantsAnnotation($annotation): bool { - return $annotation !== null && strpos($annotation, static::PREFIX) !== false; + return $annotation !== null && str_contains($annotation, static::PREFIX); } /** * @param VirtualMachine $vm + * + * @return void */ - public function handle(VirtualMachine $vm) + public function handle(VirtualMachine $vm): void { $this->parseAnnotation($vm->get('annotation')); $this->parseCustomValues($vm->customValues()); @@ -45,7 +52,7 @@ public function handle(VirtualMachine $vm) * * @param CustomValues $values */ - protected function parseCustomValues(CustomValues $values) + protected function parseCustomValues(CustomValues $values): void { $attributes = []; foreach ($this->getCustomValues() as $name) { @@ -61,9 +68,10 @@ protected function parseCustomValues(CustomValues $values) /** * @param VirtualMachine $vm + * * @return bool */ - public function wants(VirtualMachine $vm) + public function wants(VirtualMachine $vm): bool { $values = $vm->customValues(); foreach ($this->getCustomValues() as $name) { @@ -76,9 +84,9 @@ public function wants(VirtualMachine $vm) } /** - * @return array|null + * @return ?array */ - public function getAttributes() + public function getAttributes(): ?array { return $this->lastAttributes; } @@ -86,7 +94,7 @@ public function getAttributes() /** * @return array */ - public function requireParsedAttributes() + public function requireParsedAttributes(): array { $attributes = $this->getAttributes(); if ($attributes === null) { @@ -96,7 +104,12 @@ public function requireParsedAttributes() return $attributes; } - protected function parseAnnotation($annotation) + /** + * @param ?string $annotation + * + * @return void + */ + protected function parseAnnotation(?string $annotation): void { if ($annotation === null) { return; @@ -119,7 +132,7 @@ protected function parseAnnotation($annotation) $parts = preg_split('/],\s/', rtrim($match, ']')); $attributes = []; foreach ($parts as $part) { - if (strpos($part, ': [') === false) { + if (! str_contains($part, ': [')) { continue; } [$key, $value] = preg_split('/:\s\[/', $part, 2); @@ -131,7 +144,12 @@ protected function parseAnnotation($annotation) $this->lastAttributes = $attributes; } - public function stripAnnotation(&$annotation) + /** + * @param string $annotation + * + * @return void + */ + public function stripAnnotation(string &$annotation): void { $begin = strpos($annotation, static::PREFIX); if ($begin === false) { @@ -143,18 +161,27 @@ public function stripAnnotation(&$annotation) $end = strlen($annotation); } - $annotation = substr($annotation, 0, $begin) - . substr($annotation, $end); + $annotation = substr($annotation, 0, $begin) . substr($annotation, $end); } - public function stripCustomValues(CustomValues $values) + /** + * @param CustomValues $values + * + * @return void + */ + public function stripCustomValues(CustomValues $values): void { foreach ($this->getCustomValues() as $name) { $values->remove($name); } } - public function removeCustomValues(CustomValues $values) + /** + * @param CustomValues $values + * + * @return void + */ + public function removeCustomValues(CustomValues $values): void { foreach ($this->getCustomValues() as $name) { $values->remove($name); diff --git a/library/Vspheredb/Addon/VRangerBackup.php b/library/Vspheredb/Addon/VRangerBackup.php index bae060b0..8b779103 100644 --- a/library/Vspheredb/Addon/VRangerBackup.php +++ b/library/Vspheredb/Addon/VRangerBackup.php @@ -8,9 +8,10 @@ class VRangerBackup extends SimpleBackupTool { public const PREFIX = 'vRanger Backup & Replication:'; - protected $lastAttributes; - - public function getName() + /** + * @return string + */ + public function getName(): string { return 'vRanger Backup & Replication'; } @@ -18,12 +19,17 @@ public function getName() /** * @return VRangerBackupRunDetails */ - public function getInfoRenderer() + public function getInfoRenderer(): VRangerBackupRunDetails { return new VRangerBackupRunDetails($this); } - protected function parseAnnotation($annotation) + /** + * @param ?string $annotation + * + * @return void + */ + protected function parseAnnotation(?string $annotation): void { $this->lastAttributes = null; $begin = strpos($annotation, static::PREFIX); diff --git a/library/Vspheredb/Addon/VeeamBackup.php b/library/Vspheredb/Addon/VeeamBackup.php index 7e2f5f68..d55148a7 100644 --- a/library/Vspheredb/Addon/VeeamBackup.php +++ b/library/Vspheredb/Addon/VeeamBackup.php @@ -10,24 +10,30 @@ class VeeamBackup extends SimpleBackupTool { public const PREFIX = 'Veeam Backup: '; - public function getName() + /** + * @return string + */ + public function getName(): string { return 'Veeam Backup & Replication'; } /** * @param VirtualMachine $vm + * * @return bool */ - public function wants(VirtualMachine $vm) + public function wants(VirtualMachine $vm): bool { return $this->wantsAnnotation($vm->get('annotation')); } /** * @param VirtualMachine $vm + * + * @return void */ - public function handle(VirtualMachine $vm) + public function handle(VirtualMachine $vm): void { $this->parseAnnotation($vm->get('annotation')); } @@ -35,7 +41,7 @@ public function handle(VirtualMachine $vm) /** * @return VeeamBackupRunDetails */ - public function getInfoRenderer() + public function getInfoRenderer(): VeeamBackupRunDetails { return new VeeamBackupRunDetails($this); } @@ -43,7 +49,7 @@ public function getInfoRenderer() /** * @return array */ - public function requireParsedAttributes() + public function requireParsedAttributes(): array { $attributes = $this->getAttributes(); if ($attributes === null) { diff --git a/library/Vspheredb/Api/Protocol/ClientDecoder.php b/library/Vspheredb/Api/Protocol/ClientDecoder.php index 6067300e..bd0b8d36 100644 --- a/library/Vspheredb/Api/Protocol/ClientDecoder.php +++ b/library/Vspheredb/Api/Protocol/ClientDecoder.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Api\Protocol; +use ReturnTypeWillChange; use SoapClient; use SoapFault; @@ -13,17 +14,19 @@ */ final class ClientDecoder extends SoapClient { - private $response = null; + private ?string $response = null; /** * Decodes the SOAP response / return value from the given SOAP envelope (HTTP response body) * * @param string $function * @param string $response + * * @return mixed + * * @throws SoapFault if response indicates a fault (error condition) or is invalid */ - public function decode($function, $response) + public function decode(string $function, string $response): mixed { // Temporarily save response internally for further processing $this->response = $response; @@ -48,7 +51,7 @@ public function decode($function, $response) * * @see SoapClient::__doRequest() */ - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function __doRequest($request, $location, $action, $version, $oneWay = 0, $uriParserClass = null) { // the actual result doesn't actually matter, just return the given result diff --git a/library/Vspheredb/Api/Protocol/ClientEncoder.php b/library/Vspheredb/Api/Protocol/ClientEncoder.php index fea558fc..cfbcc2b1 100644 --- a/library/Vspheredb/Api/Protocol/ClientEncoder.php +++ b/library/Vspheredb/Api/Protocol/ClientEncoder.php @@ -2,8 +2,9 @@ namespace Icinga\Module\Vspheredb\Api\Protocol; -use SoapClient; use GuzzleHttp\Psr7\Request; +use ReturnTypeWillChange; +use SoapClient; use SoapFault; /** @@ -14,17 +15,19 @@ */ final class ClientEncoder extends SoapClient { - private $request = null; + private ?Request $request = null; /** * Encodes the given RPC function name and arguments as a SOAP request * * @param string $name * @param array $args + * * @return Request + * * @throws SoapFault if request is invalid according to WSDL */ - public function encode($name, $args) + public function encode(string $name, array $args): Request { $this->__soapCall($name, $args); @@ -46,7 +49,7 @@ public function encode($name, $args) * * @see SoapClient::__doRequest() */ - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function __doRequest($request, $location, $action, $version, $oneWay = 0, $uriParserClass = null) { $headers = []; diff --git a/library/Vspheredb/Api/SoapClient.php b/library/Vspheredb/Api/SoapClient.php index 3f7ab4b3..c76e53e8 100644 --- a/library/Vspheredb/Api/SoapClient.php +++ b/library/Vspheredb/Api/SoapClient.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Api; +use Exception; use gipfl\Curl\CurlAsync; use gipfl\Json\JsonEncodeException; use gipfl\Json\JsonString; @@ -22,30 +23,32 @@ */ class SoapClient { - /** @var array */ - protected $curlOptions; + protected array $curlOptions; - private $curl; + private CurlAsync $curl; - private $encoder; + private ClientEncoder $encoder; - private $decoder; + private ClientDecoder $decoder; - /** @var CookieStore */ - protected $cookieStore; + protected ?CookieStore $cookieStore = null; - protected $logger; + protected LoggerInterface $logger; /** - * @param CurlAsync $curl - * @param string|null $wsdl - * @param array $options + * @param CurlAsync $curl + * @param ?string $wsdl + * @param array $options + * @param array $curlOptions + * @param ?LoggerInterface $logger + * + * @throws SoapFault */ public function __construct( CurlAsync $curl, - $wsdl, + ?string $wsdl, array $options = [], - $curlOptions = [], + array $curlOptions = [], ?LoggerInterface $logger = null ) { $this->curl = $curl; @@ -55,31 +58,29 @@ public function __construct( $this->logger = $logger ?: new NullLogger(); } - public function setCookieStore(CookieStore $cookieStore) + public function setCookieStore(CookieStore $cookieStore): void { $this->cookieStore = $cookieStore; } /** * @param string $method - * @param mixed[] $args + * @param array $args + * * @return PromiseInterface */ - public function call($method, $args): PromiseInterface + public function call(string $method, array $args): PromiseInterface { - $request = $this->addCookiesToRequest( - $this->encoder->encode($method, $args), - $method - ); + $request = $this->addCookiesToRequest($this->encoder->encode($method, $args), $method); return $this->curl->send($request, $this->curlOptions) ->then(function (ResponseInterface $response) use ($method) { try { - $result = $this->decoder->decode($method, (string)$response->getBody()); + $result = $this->decoder->decode($method, (string) $response->getBody()); $this->checkResponseForCookies($response); return $result; - } catch (\Exception $e) { + } catch (Exception $e) { if ($e instanceof SoapFault) { if ($e->getMessage() === 'looks like we got no XML document') { throw new SoapFault( @@ -110,24 +111,22 @@ public function call($method, $args): PromiseInterface $status = $response->getStatusCode(); if ($status > 199 && $status <= 299) { - throw new \Exception($response->getReasonPhrase()); + throw new Exception($response->getReasonPhrase()); } - $this->logger->error( - 'Failing Response: ' . $this->getBodyPart($response) - ); + $this->logger->error('Failing Response: ' . $this->getBodyPart($response)); throw $e; } }); } - protected function getBodyPart(ResponseInterface $response) + protected function getBodyPart(ResponseInterface $response): string { return str_replace(["\r", "\n"], ['\\r', '\\n'], substr($response->getBody(), 0, 800)); } - protected function addCookiesToRequest(RequestInterface $request, $soapFunctionName) + protected function addCookiesToRequest(RequestInterface $request, $soapFunctionName): RequestInterface { if ($this->cookieStore && $this->cookieStore->hasCookies()) { foreach ($this->cookieStore->getCookies() as $cookie) { @@ -138,7 +137,7 @@ protected function addCookiesToRequest(RequestInterface $request, $soapFunctionN return $request; } - protected function checkResponseForCookies(ResponseInterface $response) + protected function checkResponseForCookies(ResponseInterface $response): void { if ($this->cookieStore) { $cookies = $response->getHeader('set-cookie'); diff --git a/library/Vspheredb/Application/Dependency.php b/library/Vspheredb/Application/Dependency.php deleted file mode 100644 index 929a3f8f..00000000 --- a/library/Vspheredb/Application/Dependency.php +++ /dev/null @@ -1,113 +0,0 @@ -=1.7.0 - * @param string $installedVersion - * @param bool $enabled - */ - public function __construct($name, $requirement, $installedVersion = null, $enabled = null) - { - $this->name = $name; - $this->setRequirement($requirement); - if ($installedVersion !== null) { - $this->setInstalledVersion($installedVersion); - } - if ($enabled !== null) { - $this->setEnabled($enabled); - } - } - - public function setRequirement($requirement) - { - if (preg_match('/^([<>=]+)\s*v?(\d+\.\d+\.\d+)$/', $requirement, $match)) { - $this->operator = $match[1]; - $this->requiredVersion = $match[2]; - $this->requirement = $requirement; - } else { - throw new \InvalidArgumentException("'$requirement' is not a valid version constraint"); - } - } - - /** - * @return bool - */ - public function isInstalled() - { - return $this->installedVersion !== null; - } - - /** - * @return string|null - */ - public function getInstalledVersion() - { - return $this->installedVersion; - } - - /** - * @param string $version - */ - public function setInstalledVersion($version) - { - $this->installedVersion = ltrim($version, 'v'); // v0.6.0 VS 0.6.0 - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->enabled === true; - } - - /** - * @param bool $enabled - */ - public function setEnabled($enabled = true) - { - $this->enabled = $enabled; - } - - public function isSatisfied() - { - if (! $this->isInstalled() || ! $this->isEnabled()) { - return false; - } - - return version_compare($this->installedVersion, $this->requiredVersion, $this->operator); - } - - public function getName() - { - return $this->name; - } - - public function getRequirement() - { - return $this->requirement; - } -} diff --git a/library/Vspheredb/Application/DependencyChecker.php b/library/Vspheredb/Application/DependencyChecker.php deleted file mode 100644 index 27fbf17a..00000000 --- a/library/Vspheredb/Application/DependencyChecker.php +++ /dev/null @@ -1,73 +0,0 @@ -app = $app; - $this->modules = $app->getModuleManager(); - } - - /** - * @param Module $module - * @return Dependency[] - */ - public function getDependencies(Module $module) - { - $dependencies = []; - $isV290 = version_compare(Version::VERSION, '2.9.0', '>='); - foreach ($module->getDependencies() as $moduleName => $required) { - if ($isV290 && in_array($moduleName, ['ipl', 'reactbundle'], true)) { - continue; - } - $dependency = new Dependency($moduleName, $required); - $dependency->setEnabled($this->modules->hasEnabled($moduleName)); - if ($this->modules->hasInstalled($moduleName)) { - $dependency->setInstalledVersion($this->modules->getModule($moduleName, false)->getVersion()); - } - $dependencies[] = $dependency; - } - if ($isV290) { - $libs = $this->app->getLibraries(); - foreach ($module->getRequiredLibraries() as $libraryName => $required) { - $dependency = new Dependency($libraryName, $required); - if ($libs->has($libraryName)) { - $dependency->setInstalledVersion($libs->get($libraryName)->getVersion()); - $dependency->setEnabled(); - } - $dependencies[] = $dependency; - } - } - - return $dependencies; - } - - // if (version_compare(Version::VERSION, '2.9.0', 'ge')) { - // } - /** - * @param Module $module - * @return bool - */ - public function satisfiesDependencies(Module $module) - { - foreach ($this->getDependencies($module) as $dependency) { - if (! $dependency->isSatisfied()) { - return false; - } - } - - return true; - } -} diff --git a/library/Vspheredb/Application/MemoryLimit.php b/library/Vspheredb/Application/MemoryLimit.php index 04c4d04f..b7d12a3d 100644 --- a/library/Vspheredb/Application/MemoryLimit.php +++ b/library/Vspheredb/Application/MemoryLimit.php @@ -4,7 +4,12 @@ class MemoryLimit { - public static function raiseTo($string) + /** + * @param string $string + * + * @return void + */ + public static function raiseTo(string $string): void { $current = static::getBytes(); $desired = static::parsePhpIniByteString($string); @@ -13,7 +18,10 @@ public static function raiseTo($string) } } - public static function getBytes() + /** + * @return int + */ + public static function getBytes(): int { return static::parsePhpIniByteString((string) ini_get('memory_limit')); } @@ -27,10 +35,11 @@ public static function getBytes() * > (for Gigabytes), and are all case-insensitive. Anything else assumes * > bytes. * - * @param $string + * @param string $string + * * @return int */ - public static function parsePhpIniByteString($string) + public static function parsePhpIniByteString(string $string): int { $val = trim($string); diff --git a/library/Vspheredb/Auth/RestrictionHelper.php b/library/Vspheredb/Auth/RestrictionHelper.php index 104fe752..84e0c0d0 100644 --- a/library/Vspheredb/Auth/RestrictionHelper.php +++ b/library/Vspheredb/Auth/RestrictionHelper.php @@ -10,18 +10,22 @@ use Icinga\Module\Vspheredb\Db\DbUtil; use Icinga\Module\Vspheredb\Web\Table\TableWithVCenterFilter; use Ramsey\Uuid\Uuid; +use Zend_Db_Adapter_Abstract; +use Zend_Db_Select; class RestrictionHelper { - /** @var Auth */ - protected $auth; + protected Auth $auth; - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; - /** @var string[]|null */ - protected $restrictedVCenterUuids = null; + /** @var ?string[] */ + protected ?array $restrictedVCenterUuids = null; + /** + * @param Auth $auth + * @param Db $connection + */ public function __construct(Auth $auth, Db $connection) { $this->db = $connection->getDbAdapter(); @@ -29,14 +33,25 @@ public function __construct(Auth $auth, Db $connection) $this->loadRestrictedVCenterList(); } - public function restrictTable(TableWithVCenterFilter $table) + /** + * @param TableWithVCenterFilter $table + * + * @return void + */ + public function restrictTable(TableWithVCenterFilter $table): void { if ($this->restrictedVCenterUuids) { $table->filterVCenterUuids($this->restrictedVCenterUuids); } } - public function filterQuery($query, $vCenterColumn = 'vcenter_uuid') + /** + * @param Zend_Db_Select $query + * @param string $vCenterColumn + * + * @return void + */ + public function filterQuery(Zend_Db_Select $query, string $vCenterColumn = 'vcenter_uuid'): void { $uuids = $this->restrictedVCenterUuids; if ($uuids === null) { @@ -49,14 +64,26 @@ public function filterQuery($query, $vCenterColumn = 'vcenter_uuid') } } - public function assertAccessToVCenterUuidIsGranted($uuid) + /** + * @param string $uuid + * + * @return void + * + * @throws NotFoundError + */ + public function assertAccessToVCenterUuidIsGranted(string $uuid): void { if (! $this->allowsVCenter($uuid)) { throw new NotFoundError('Not found'); } } - public function allowsVCenter($uuid): bool + /** + * @param string $uuid + * + * @return bool + */ + public function allowsVCenter(string $uuid): bool { if ($this->restrictedVCenterUuids === null) { return true; @@ -68,7 +95,10 @@ public function allowsVCenter($uuid): bool return in_array($uuid, $this->restrictedVCenterUuids); } - public function loadRestrictedVCenterList() + /** + * @return void + */ + public function loadRestrictedVCenterList(): void { $uuids = null; $restrictions = $this->auth->getRestrictions('vspheredb/vcenters'); diff --git a/library/Vspheredb/CheckPluginHelper.php b/library/Vspheredb/CheckPluginHelper.php index e4b21705..abdf3efe 100644 --- a/library/Vspheredb/CheckPluginHelper.php +++ b/library/Vspheredb/CheckPluginHelper.php @@ -3,67 +3,64 @@ namespace Icinga\Module\Vspheredb; use Exception; +use gipfl\Cli\AnsiScreen; use gipfl\Cli\Screen; use Icinga\Module\Vspheredb\Clicommands\Command; use Icinga\Module\Vspheredb\Data\Anonymizer; use InvalidArgumentException; use React\Promise\PromiseInterface; +use Throwable; trait CheckPluginHelper { - /** @var int */ - protected $state = 0; + protected int $state = 0; protected $sortingState; - protected $sortingStateMap = [0, 1, 3, 2]; + protected array $sortingStateMap = [0, 1, 3, 2]; - protected $outputScreen; + protected AnsiScreen|Screen|null $outputScreen = null; - /** @var array */ - protected $nameStateMap = [ + protected array $nameStateMap = [ 'OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, - 'UNKNOWN' => 3, + 'UNKNOWN' => 3 ]; - /** @var array */ - protected $stateNameMap = [ + protected array $stateNameMap = [ 'OK', 'WARNING', 'CRITICAL', - 'UNKNOWN', + 'UNKNOWN' ]; - protected $stateColors = [ + protected array $stateColors = [ 'OK' => 'green', 'WARNING' => 'brown', 'CRITICAL' => 'red', - 'UNKNOWN' => 'purple', + 'UNKNOWN' => 'purple' ]; - /** @var array */ - protected $messages = []; + protected array $messages = []; - /** @var string|null */ - protected $message; + protected ?string $message = null; /** - * @param $callable + * @param callable $callable */ - protected function run($callable) + protected function run(callable $callable): void { /** @var Command $this */ $this->loop()->futureTick(function () use ($callable) { $result = null; - if (\is_callable($callable)) { + if (is_callable($callable)) { try { $result = $callable(); } catch (Exception $e) { $this->addProblem('UNKNOWN', $this->stripNonUtf8Characters($e->getMessage())); $this->showOptionalTrace($e); - } catch (\Throwable $e) { + } catch (Throwable $e) { $this->addProblem('UNKNOWN', $this->stripNonUtf8Characters($e->getMessage())); $this->showOptionalTrace($e); } @@ -87,7 +84,7 @@ protected function run($callable) $this->eventuallyStartMainLoop(); } - protected function showOptionalTrace($e) + protected function showOptionalTrace(Throwable $e): void { if ($this->showTrace()) { echo $e->getTraceAsString(); @@ -96,29 +93,32 @@ protected function showOptionalTrace($e) /** * @param string $string + * * @return string */ - protected function stripNonUtf8Characters($string) + protected function stripNonUtf8Characters(string $string): string { return iconv('UTF-8', 'UTF-8//IGNORE', $string); } /** * @param int|string|null $state + * * @return string */ protected function getStateName(int|string|null $state = null): string { if ($state === null) { return $this->stateNameMap[$this->state]; - } else { - return $this->stateNameMap[$this->wantNumericState($state)]; } + + return $this->stateNameMap[$this->wantNumericState($state)]; } /** * @param int|string $state * @param string $message + * * @return $this */ protected function addProblem(int|string $state, string $message): static @@ -134,20 +134,17 @@ protected function addProblem(int|string $state, string $message): static return $this; } - protected function getOutputScreen() + protected function getOutputScreen(): AnsiScreen|Screen { - if ($this->outputScreen === null) { - $this->outputScreen = Screen::factory(); - } - - return $this->outputScreen; + return $this->outputScreen ??= Screen::factory(); } /** * @param string $message + * * @return $this */ - protected function addMessage($message) + protected function addMessage(string $message): static { $this->messages[] = $message; @@ -156,9 +153,10 @@ protected function addMessage($message) /** * @param string $message + * * @return $this */ - protected function prependMessage($message) + protected function prependMessage(string $message): static { array_unshift($this->messages, $message); @@ -167,6 +165,7 @@ protected function prependMessage($message) /** * @param int|string $state + * * @return $this */ protected function raiseState(int|string $state): static @@ -182,13 +181,14 @@ protected function raiseState(int|string $state): static /** * @return int */ - protected function getState() + protected function getState(): int { return $this->state; } /** * @param int|string $state + * * @return int */ protected function wantNumericState(int|string $state): int @@ -196,24 +196,24 @@ protected function wantNumericState(int|string $state): int if (is_int($state) || ctype_digit($state)) { if (array_key_exists($state, $this->stateNameMap)) { return (int) $state; - } else { - throw new InvalidArgumentException(sprintf('%d is not a valid numeric state', $state)); - } - } else { - if (array_key_exists($state, $this->nameStateMap)) { - return $this->nameStateMap[$state]; - } else { - throw new InvalidArgumentException(sprintf('%s is not a valid state name', $state)); } + + throw new InvalidArgumentException(sprintf('%d is not a valid numeric state', $state)); + } + + if (array_key_exists($state, $this->nameStateMap)) { + return $this->nameStateMap[$state]; } + + throw new InvalidArgumentException(sprintf('%s is not a valid state name', $state)); } - protected function getMessages() + protected function getMessages(): array { return $this->messages; } - protected function shutdown() + protected function shutdown(): void { $messages = $this->getMessages(); if (! empty($messages)) { @@ -221,6 +221,7 @@ protected function shutdown() } $this->loop()->addTimer(0.01, function () { $this->loop()->stop(); + exit($this->getState()); }); } diff --git a/library/Vspheredb/Configuration.php b/library/Vspheredb/Configuration.php index 251fddc5..33cafe14 100644 --- a/library/Vspheredb/Configuration.php +++ b/library/Vspheredb/Configuration.php @@ -9,19 +9,11 @@ class Configuration { public const DEFAULT_SOCKET = '/run/icinga-vspheredb/vspheredb.sock'; - private static $controlSocket; + private static ?string $controlSocket = null; - public static function getSocketPath() + public static function getSocketPath(): string { - if (self::$controlSocket === null) { - if ($path = getenv('VSPHEREDB_SOCKET')) { - static::setControlSocket($path); - } else { - static::setControlSocket(self::DEFAULT_SOCKET); - } - } - - return self::$controlSocket; + return self::$controlSocket ??= getenv('VSPHEREDB_SOCKET') ?: self::DEFAULT_SOCKET; } /** @@ -29,9 +21,9 @@ public static function getSocketPath() * * Used for testing reasons only. Set null to re-enable the default logic * - * @param $path + * @param string $path */ - public static function setControlSocket($path) + public static function setControlSocket(string $path): void { self::$controlSocket = $path; } diff --git a/library/Vspheredb/Daemon/ConfigWatch.php b/library/Vspheredb/Daemon/ConfigWatch.php index 811a658b..1518b214 100644 --- a/library/Vspheredb/Daemon/ConfigWatch.php +++ b/library/Vspheredb/Daemon/ConfigWatch.php @@ -19,27 +19,24 @@ class ConfigWatch public const ON_CONFIG = 'dbConfig'; - /** @var string */ - protected $configFile; + protected string $configFile; - /** @var string */ - protected $resourceConfigFile; + protected ?string $resourceConfigFile = null; - /** @var string|null */ - protected $dbResourceName; + protected ?string $dbResourceName = null; - /** @var array|null */ - protected $resourceConfig; + protected ?array $resourceConfig = null; - protected $interval = 3; + protected int $interval = 3; - /** @var TimerInterface */ - protected $timer; + protected ?TimerInterface $timer = null; - /** @var LoopInterface */ - protected $loop; + protected ?LoopInterface $loop = null; - public function __construct($dbResourceName = null) + /** + * @param ?string $dbResourceName + */ + public function __construct(?string $dbResourceName = null) { $this->configFile = Config::module('vspheredb')->getConfigFile(); if ($dbResourceName === null) { @@ -51,8 +48,10 @@ public function __construct($dbResourceName = null) /** * @param LoopInterface $loop + * + * @return void */ - public function run(LoopInterface $loop) + public function run(LoopInterface $loop): void { $this->loop = $loop; $check = function () { @@ -62,7 +61,10 @@ public function run(LoopInterface $loop) $loop->futureTick($check); } - public function stop() + /** + * @return void + */ + public function stop(): void { if ($this->timer) { $this->loop->cancelTimer($this->timer); @@ -70,33 +72,40 @@ public function stop() } } - protected function checkForFreshConfig() + /** + * @return void + */ + protected function checkForFreshConfig(): void { if ($this->configHasBeenChanged()) { $this->emit(self::ON_CONFIG, [$this->resourceConfig]); } } - protected function getResourceName() + /** + * @return ?string + */ + protected function getResourceName(): ?string { - if ($this->dbResourceName) { - return $this->dbResourceName; - } else { - return $this->loadDbResourceName(); - } + return $this->dbResourceName ?: $this->loadDbResourceName(); } - protected function loadDbResourceName() + /** + * @return ?string + */ + protected function loadDbResourceName(): ?string { $parsed = @parse_ini_file($this->configFile, true); - if (isset($parsed['db']['resource'])) { - return $parsed['db']['resource']; - } else { - return null; - } + + return $parsed['db']['resource'] ?? null; } - protected function loadDbConfigFromDisk($name) + /** + * @param ?string $name + * + * @return ?array + */ + protected function loadDbConfigFromDisk(?string $name): ?array { if ($name === null) { return null; @@ -108,20 +117,23 @@ protected function loadDbConfigFromDisk($name) ksort($section); return $section; - } else { - return null; } + + return null; } - protected function configHasBeenChanged() + /** + * @return bool + */ + protected function configHasBeenChanged(): bool { $resource = $this->loadDbConfigFromDisk($this->loadDbResourceName()); if ($resource !== $this->resourceConfig) { $this->resourceConfig = $resource; return true; - } else { - return false; } + + return false; } } diff --git a/library/Vspheredb/Daemon/ConnectionState.php b/library/Vspheredb/Daemon/ConnectionState.php index 647ad466..b81f7f83 100644 --- a/library/Vspheredb/Daemon/ConnectionState.php +++ b/library/Vspheredb/Daemon/ConnectionState.php @@ -8,20 +8,19 @@ use Icinga\Module\Vspheredb\Monitoring\Health\ApiConnectionInfo; use Icinga\Module\Vspheredb\Monitoring\Health\ServerConnectionInfo; use Icinga\Module\Vspheredb\Polling\ApiConnection; +use Zend_Db_Adapter_Abstract; class ConnectionState { - /** @var array */ - protected $daemonApiConnections; + protected array $daemonApiConnections; - /** @var Adapter|\Zend_Db_Adapter_Abstract */ - protected $db; + protected Adapter|Zend_Db_Adapter_Abstract $db; /** * @param ApiConnectionInfo[] $daemonApiConnections - * @param Adapter|\Zend_Db_Adapter_Abstract $db + * @param Zend_Db_Adapter_Abstract|Adapter $db */ - public function __construct(array $daemonApiConnections, $db) + public function __construct(array $daemonApiConnections, Zend_Db_Adapter_Abstract|Adapter $db) { $this->daemonApiConnections = []; foreach ($daemonApiConnections as $connection) { @@ -57,6 +56,9 @@ public function getConnectionsByVCenter(): array return $connectionsByVCenter; } + /** + * @return array + */ protected function getConfiguredServersByVCenter(): array { $db = $this->db; @@ -88,17 +90,22 @@ protected function getConfiguredServersByVCenter(): array return $result; } + /** + * @param ServerConnectionInfo $info + * + * @return string + */ public static function describe(ServerConnectionInfo $info): string { $t = StaticTranslator::get(); $state = $info->getState(); - $label = $info->serverName; - $label = Anonymizer::anonymizeString($label); - $lastError = $info->apiConnection ? $info->apiConnection->lastErrorMessage : null; + $label = Anonymizer::anonymizeString($info->serverName); + $lastError = $info->apiConnection?->lastErrorMessage; if ($lastError) { $lastError = ": $lastError"; $lastError = Anonymizer::anonymizeString($lastError); } + switch ($state) { case 'unknown': return sprintf( @@ -106,41 +113,26 @@ public static function describe(ServerConnectionInfo $info): string $label ) . $lastError; case 'disabled': - return sprintf( - $t->translate('Connections to %s have been disabled'), - $label - ); + return sprintf($t->translate('Connections to %s have been disabled'), $label); case ApiConnection::STATE_CONNECTED: - return sprintf( - $t->translate('API connection with %s is fine'), - $label - ); + return sprintf($t->translate('API connection with %s is fine'), $label); case ApiConnection::STATE_LOGIN: - return sprintf( - $t->translate('Trying to log in to %s'), - $label - ) . $lastError; + return sprintf($t->translate('Trying to log in to %s'), $label) . $lastError; case ApiConnection::STATE_INIT: - return sprintf( - $t->translate('Initializing API connection with %s'), - $label - ) . $lastError; + return sprintf($t->translate('Initializing API connection with %s'), $label) . $lastError; case ApiConnection::STATE_FAILING: - return sprintf( - $t->translate('API connection with %s is failing'), - $label - ) . $lastError; + return sprintf($t->translate('API connection with %s is failing'), $label) . $lastError; case ApiConnection::STATE_STOPPING: - return sprintf( - $t->translate('Stopping API connection with %s'), - $label - ) . $lastError; + return sprintf($t->translate('Stopping API connection with %s'), $label) . $lastError; default: return $t->translate("Unknown API connection state: $state") . $lastError; } } - public static function describeNoServer() + /** + * @return string + */ + public static function describeNoServer(): string { return StaticTranslator::get()->translate('There is no configured server for this vCenter'); } diff --git a/library/Vspheredb/Daemon/ControlSocket.php b/library/Vspheredb/Daemon/ControlSocket.php index 06954e39..f6dfbdc3 100644 --- a/library/Vspheredb/Daemon/ControlSocket.php +++ b/library/Vspheredb/Daemon/ControlSocket.php @@ -16,28 +16,36 @@ class ControlSocket implements EventEmitterInterface { use EventEmitterTrait; - /** @var string */ - protected $path; + protected string $path; - /** @var LoopInterface */ - protected $loop; + protected ?LoopInterface $loop = null; - /** @var UnixServer */ - protected $server; + protected ?UnixServer $server = null; - public function __construct($path) + /** + * @param string $path + */ + public function __construct(string $path) { $this->path = $path; $this->eventuallyRemoveSocketFile(); } - public function run(LoopInterface $loop) + /** + * @param LoopInterface $loop + * + * @return void + */ + public function run(LoopInterface $loop): void { $this->loop = $loop; $this->listen(); } - protected function listen() + /** + * @return void + */ + protected function listen(): void { $old = umask(0000); $server = new UnixServer('unix://' . $this->path, $this->loop); @@ -46,17 +54,21 @@ protected function listen() $this->server = $server; } - public function shutdown() + /** + * @return void + */ + public function shutdown(): void { - if ($this->server) { - $this->server->close(); - $this->server = null; - } + $this->server?->close(); + $this->server = null; $this->eventuallyRemoveSocketFile(); } - protected function eventuallyRemoveSocketFile() + /** + * @return void + */ + protected function eventuallyRemoveSocketFile(): void { if (file_exists($this->path)) { unlink($this->path); diff --git a/library/Vspheredb/Daemon/DbCleanup.php b/library/Vspheredb/Daemon/DbCleanup.php index 34246629..3095d70b 100644 --- a/library/Vspheredb/Daemon/DbCleanup.php +++ b/library/Vspheredb/Daemon/DbCleanup.php @@ -2,28 +2,30 @@ namespace Icinga\Module\Vspheredb\Daemon; -use gipfl\Log\Logger; use gipfl\ZfDb\Adapter\Adapter; use Psr\Log\LoggerInterface; +use Zend_Db_Adapter_Abstract; class DbCleanup { - protected $db; + protected Adapter|Zend_Db_Adapter_Abstract $db; - /** @var Logger */ - protected $logger; + protected LoggerInterface $logger; /** - * @param Adapter|\Zend_Db_Adapter_Abstract $db + * @param Adapter|Zend_Db_Adapter_Abstract $db * @param LoggerInterface $logger */ - public function __construct($db, LoggerInterface $logger) + public function __construct(Adapter|Zend_Db_Adapter_Abstract $db, LoggerInterface $logger) { $this->db = $db; $this->logger = $logger; } - public function runForStartup() + /** + * @return void + */ + public function runForStartup(): void { $this->logger->notice('Running DB cleanup (this could take some time)'); $db = $this->db; @@ -55,7 +57,10 @@ public function runForStartup() $this->logger->notice('DB has been cleaned up'); } - public function runRegular() + /** + * @return void + */ + public function runRegular(): void { $this->logger->notice('Running DB cleanup (this could take some time)'); $db = $this->db; @@ -65,12 +70,15 @@ public function runRegular() $this->logger->notice('DB has been cleaned up'); } - protected function optimizeWhenDeleted($result) + /** + * @param int $result + * + * @return void + */ + protected function optimizeWhenDeleted(int $result): void { if ($result > 0) { - $this->logger->info( - "Removed $result outdated daemon log lines, optimizing table" - ); + $this->logger->info("Removed $result outdated daemon log lines, optimizing table"); $this->db->query('OPTIMIZE TABLE vspheredb_daemonlog')->execute(); } } diff --git a/library/Vspheredb/Daemon/DbLogger.php b/library/Vspheredb/Daemon/DbLogger.php index 580c2984..a2a9b3a3 100644 --- a/library/Vspheredb/Daemon/DbLogger.php +++ b/library/Vspheredb/Daemon/DbLogger.php @@ -11,6 +11,7 @@ use Psr\Log\LoggerAwareTrait; use Ramsey\Uuid\Uuid; use SplStack; +use Zend_Db_Adapter_Abstract; class DbLogger implements LogWriterWithContext, EventEmitterInterface { @@ -21,19 +22,24 @@ class DbLogger implements LogWriterWithContext, EventEmitterInterface public const ERROR_PREFIX_LENGTH = 17; - protected $instance; + protected string $instance; - protected $db; + protected ?Zend_Db_Adapter_Abstract $db = null; - protected $queue; + protected SplStack $queue; - protected $fqdn; + protected string $fqdn; - protected $pid; + protected int $pid; - protected $lastTs = null; + protected ?int $lastTs = null; - public function __construct($instanceUuid, $fqdn, $pid) + /** + * @param string $instanceUuid + * @param string $fqdn + * @param int $pid + */ + public function __construct(string $instanceUuid, string $fqdn, int $pid) { $this->instance = $instanceUuid; $this->fqdn = $fqdn; @@ -41,7 +47,12 @@ public function __construct($instanceUuid, $fqdn, $pid) $this->queue = new SplStack(); } - public function setDb(?Db $db = null) + /** + * @param ?Db $db + * + * @return void + */ + public function setDb(?Db $db = null): void { if ($db === null) { $this->db = null; @@ -51,7 +62,14 @@ public function setDb(?Db $db = null) } } - public function write($level, $message, $context = []) + /** + * @param string $level + * @param string $message + * @param array $context + * + * @return void + */ + public function write($level, $message, $context = []): void { if (substr($message, 0, self::ERROR_PREFIX_LENGTH) === self::ERROR_PREFIX) { return; @@ -67,7 +85,7 @@ public function write($level, $message, $context = []) 'timestamp' => $timestamp, 'level' => $level, 'message' => $message, - 'context' => $context, + 'context' => $context ]); if ($this->queue->count() > 100) { $this->queue->pop(); @@ -79,7 +97,15 @@ public function write($level, $message, $context = []) $this->reallyWrite($timestamp, $level, $message, $context); } - protected function reallyWrite($timestamp, $level, $message, $context = []) + /** + * @param int $timestamp + * @param string $level + * @param string $message + * @param array $context + * + * @return void + */ + protected function reallyWrite(int $timestamp, string $level, string $message, array $context = []): void { $params = [ 'instance_uuid' => $this->instance, @@ -87,7 +113,7 @@ protected function reallyWrite($timestamp, $level, $message, $context = []) 'pid' => $this->pid, 'fqdn' => $this->fqdn, 'level' => $level, - 'message' => $message, + 'message' => $message ]; if (isset($context['pid'])) { $params['pid'] = $context['pid']; @@ -97,24 +123,23 @@ protected function reallyWrite($timestamp, $level, $message, $context = []) } if (isset($context['vcenter_uuid'])) { $uuid = $context['vcenter_uuid']; - if (strlen($uuid) === 16) { - $params['vcenter_uuid'] = $context['vcenter_uuid']; - } else { - $params['vcenter_uuid'] = Uuid::fromString($context['vcenter_uuid'])->getBytes(); - } + $params['vcenter_uuid'] = strlen($uuid) === 16 + ? $context['vcenter_uuid'] + : Uuid::fromString($context['vcenter_uuid'])->getBytes(); } try { $this->db->insert('vspheredb_daemonlog', $params); } catch (Exception $e) { - if ($this->logger) { - $this->logger->debug(self::ERROR_PREFIX . $e->getMessage()); - } + $this->logger?->debug(self::ERROR_PREFIX . $e->getMessage()); $this->emit('error', [$e]); } } - protected function flushQueue() + /** + * @return void + */ + protected function flushQueue(): void { while (! $this->queue->isEmpty()) { $log = $this->queue->pop(); diff --git a/library/Vspheredb/Daemon/DbProcessRunner.php b/library/Vspheredb/Daemon/DbProcessRunner.php index bfa9204c..bdd541f2 100644 --- a/library/Vspheredb/Daemon/DbProcessRunner.php +++ b/library/Vspheredb/Daemon/DbProcessRunner.php @@ -4,6 +4,7 @@ use Evenement\EventEmitterInterface; use Evenement\EventEmitterTrait; +use Exception; use gipfl\Process\FinishedProcessState; use gipfl\Process\ProcessKiller; use gipfl\Protocol\JsonRpc\Handler\NamespacedPacketHandler; @@ -13,6 +14,7 @@ use React\ChildProcess\Process; use React\EventLoop\LoopInterface; use React\Promise\Deferred; +use React\Promise\PromiseInterface; use React\Stream\Util; use RuntimeException; @@ -22,29 +24,30 @@ class DbProcessRunner implements EventEmitterInterface { use EventEmitterTrait; - /** @var LoopInterface $loop */ - protected $loop; + protected ?LoopInterface $loop = null; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var JsonRpcConnection */ - protected $rpc; + protected ?JsonRpcConnection $rpc = null; - /** @var LogProxy */ - protected $logProxy; + protected ?LogProxy $logProxy = null; - /** @var Process */ - protected $process; + protected ?Process $process = null; - protected $queue = []; + protected array $queue = []; + /** + * @param LoggerInterface $logger + */ public function __construct(LoggerInterface $logger) { $this->logger = $logger; } - public function stop() + /** + * @return void + */ + public function stop(): void { if ($this->process) { $process = $this->process; @@ -55,13 +58,22 @@ public function stop() } } - protected function removeProcess() + /** + * @return void + */ + protected function removeProcess(): void { $this->process = null; $this->rpc = null; } - public function request($method, $params = []) + /** + * @param string $method + * @param array $params + * + * @return PromiseInterface + */ + public function request(string $method, array $params = []): PromiseInterface { // return $this->rpc->request($method, $params); if ($this->rpc === null) { @@ -74,14 +86,20 @@ public function request($method, $params = []) return $deferred->promise(); } - protected function scheduleNextRequest() + /** + * @return void + */ + protected function scheduleNextRequest(): void { $this->loop->futureTick(function () { $this->sendNextRequest(); }); } - protected function sendNextRequest() + /** + * @return void + */ + protected function sendNextRequest(): void { if (empty($this->queue)) { return; @@ -99,7 +117,12 @@ protected function sendNextRequest() }); } - protected function rejectQueue(\Exception $e) + /** + * @param Exception $e + * + * @return void + */ + protected function rejectQueue(Exception $e): void { foreach ($this->queue as $entry) { $entry[0]->reject($e); @@ -107,7 +130,12 @@ protected function rejectQueue(\Exception $e) $this->queue = []; } - public function run(LoopInterface $loop) + /** + * @param LoopInterface $loop + * + * @return PromiseInterface + */ + public function run(LoopInterface $loop): PromiseInterface { if ($this->process) { throw new RuntimeException('Process is already running'); diff --git a/library/Vspheredb/Daemon/IcingaCli.php b/library/Vspheredb/Daemon/IcingaCli.php index bc41c062..7730965d 100644 --- a/library/Vspheredb/Daemon/IcingaCli.php +++ b/library/Vspheredb/Daemon/IcingaCli.php @@ -6,46 +6,58 @@ use gipfl\Process\FinishedProcessState; use React\EventLoop\LoopInterface; use React\Promise\Deferred; +use React\Promise\PromiseInterface; class IcingaCli { use EventEmitterTrait; - /** @var IcingaCliRunner */ - protected $runner; + protected IcingaCliRunner $runner; - protected $arguments = []; + protected array $arguments = []; - /** @var LoopInterface */ - protected $loop; + protected ?LoopInterface $loop = null; public function __construct(?IcingaCliRunner $runner = null) { - if ($runner === null) { - $runner = IcingaCliRunner::forArgv(); - } - $this->runner = $runner; + $this->runner = $runner ?? IcingaCliRunner::forArgv(); $this->init(); } - protected function init() + /** + * @return void + */ + protected function init(): void { // Override this if you want. } - public function setArguments($arguments) + /** + * @param array $arguments + * + * @return $this + */ + public function setArguments(array $arguments): static { $this->arguments = $arguments; return $this; } - public function getArguments() + /** + * @return array + */ + public function getArguments(): array { return $this->arguments; } - public function run(LoopInterface $loop) + /** + * @param LoopInterface $loop + * + * @return PromiseInterface + */ + public function run(LoopInterface $loop): PromiseInterface { $this->loop = $loop; $process = $this->runner->command($this->getArguments()); diff --git a/library/Vspheredb/Daemon/IcingaCliRpc.php b/library/Vspheredb/Daemon/IcingaCliRpc.php index dbe6d3c4..1893f91d 100644 --- a/library/Vspheredb/Daemon/IcingaCliRpc.php +++ b/library/Vspheredb/Daemon/IcingaCliRpc.php @@ -9,22 +9,16 @@ use React\Promise\Deferred; use React\Promise\PromiseInterface; -use function React\Promise\resolve; - class IcingaCliRpc extends IcingaCli { - /** @var IcingaCliRunner */ - protected $runner; - - /** @var JsonRpcConnection */ - protected $rpc; - - /** @var Deferred */ - protected $waitingForRpc; + protected ?JsonRpcConnection $rpc = null; - protected $arguments = []; + protected ?Deferred $waitingForRpc = null; - protected function init() + /** + * @return void + */ + protected function init(): void { $this->on('start', function (Process $process) { $netString = new StreamWrapper( @@ -32,9 +26,7 @@ protected function init() $process->stdin ); $netString->on('error', function (Exception $e) { - if ($this->waitingForRpc) { - $this->waitingForRpc->reject($e); - } + $this->waitingForRpc?->reject($e); $this->emit('error', [$e]); }); $this->rpc = new JsonRpcConnection($netString); @@ -48,7 +40,7 @@ protected function init() /** * @return PromiseInterface */ - public function rpc() + public function rpc(): PromiseInterface { if (! $this->waitingForRpc) { $this->waitingForRpc = new Deferred(); diff --git a/library/Vspheredb/Daemon/IcingaCliRunner.php b/library/Vspheredb/Daemon/IcingaCliRunner.php index c83a39e1..3e33adea 100644 --- a/library/Vspheredb/Daemon/IcingaCliRunner.php +++ b/library/Vspheredb/Daemon/IcingaCliRunner.php @@ -6,25 +6,26 @@ class IcingaCliRunner { - /** @var string */ - protected $binary; + protected string $binary; - /** @var string|null */ - protected $cwd; + protected ?string $cwd = null; - /** @var array|null */ - protected $env; + protected ?array $env = null; - public function __construct($binary) + /** + * @param string $binary + */ + public function __construct(string $binary) { $this->binary = $binary; } /** - * @param array|null $argv + * @param ?array $argv + * * @return IcingaCliRunner */ - public static function forArgv(?array $argv = null) + public static function forArgv(?array $argv = null): IcingaCliRunner { if ($argv === null) { global $argv; @@ -35,13 +36,14 @@ public static function forArgv(?array $argv = null) } /** - * @param mixed array|...$arguments + * @param mixed $arguments array|...string + * * @return Process */ - public function command($arguments = null) + public function command(...$arguments): Process { - if (! is_array($arguments)) { - $arguments = func_get_args(); + if (count($arguments) === 1 && is_array($arguments[0])) { + $arguments = $arguments[0]; } return new Process( @@ -52,43 +54,36 @@ public function command($arguments = null) } /** - * @param string|null $cwd + * @param ?string $cwd + * + * @return void */ - public function setCwd($cwd) + public function setCwd(?string $cwd): void { - if ($cwd === null) { - $this->cwd = $cwd; - } else { - $this->cwd = (string) $cwd; - } + $this->cwd = $cwd; } /** - * @param array|null $env + * @param ?array $env + * + * @return void */ - public function setEnv($env) + public function setEnv(?array $env): void { - if ($env === null) { - $this->env = $env; - } else { - $this->env = (array) $env; - } + $this->env = $env; } /** - * @param $arguments + * @param array $arguments + * * @return string */ - protected function escapedCommand($arguments) + protected function escapedCommand(array $arguments): string { $command = ['exec', escapeshellcmd($this->binary)]; foreach ($arguments as $argument) { - if (ctype_alnum(preg_replace('/^\-{1,2}/', '', $argument))) { - $command[] = $argument; - } else { - $command[] = escapeshellarg($argument); - } + $command[] = ctype_alnum(preg_replace('/^\-{1,2}/', '', $argument)) ? $argument : escapeshellarg($argument); } return implode(' ', $command); diff --git a/library/Vspheredb/Daemon/ObjectSync.php b/library/Vspheredb/Daemon/ObjectSync.php index 205b39b2..625b69aa 100644 --- a/library/Vspheredb/Daemon/ObjectSync.php +++ b/library/Vspheredb/Daemon/ObjectSync.php @@ -44,24 +44,23 @@ class ObjectSync implements DaemonTask { - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; - /** @var VsphereApi */ - protected $api; + protected VsphereApi $api; /** @var LoopInterface */ protected $loop; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - protected $fastTasks = [ + /** @var string[] */ + protected array $fastTasks = [ HostQuickStatsSyncTask::class, - VmQuickStatsSyncTask::class, + VmQuickStatsSyncTask::class ]; - protected $normalTasks = [ + /** @var string[] */ + protected array $normalTasks = [ ManagedObjectReferenceSyncTask::class, HostSystemSyncTask::class, VirtualMachineSyncTask::class, @@ -70,40 +69,47 @@ class ObjectSync implements DaemonTask ComputeResourceSyncTask::class, VmDiskUsageSyncTask::class, VmDatastoreUsageSyncTask::class, - VmSnapshotSyncTask::class, + VmSnapshotSyncTask::class ]; - protected $slowTasks = [ + /** @var string[] */ + protected array $slowTasks = [ HostHardwareSyncTask::class, HostSensorSyncTask::class, HostHbaSyncTask::class, HostPhysicalNicSyncTask::class, HostVirtualNicSyncTask::class, - VmHardwareSyncTask::class, + VmHardwareSyncTask::class ]; - protected $taggingTasks = [ + /** @var string[] */ + protected array $taggingTasks = [ TaggingTagSyncTask::class, TaggingObjectTagSyncTask::class, - TaggingCategorySyncTask::class, + TaggingCategorySyncTask::class ]; /** @var TimerInterface[] */ - protected $timers = []; + protected array $timers = []; /** @var PromiseInterface[] */ - protected $runningTasks = []; + protected array $runningTasks = []; - protected $ready = false; + protected bool $ready = false; - /** @var DbProcessRunner */ - protected $dbRunner; + protected DbProcessRunner $dbRunner; - /** @var RestApi */ - protected $restApi; + protected RestApi $restApi; - protected $logTaskNames = false; + protected bool $logTaskNames = false; + /** + * @param VCenter $vCenter + * @param VsphereApi $api + * @param RestApi $restApi + * @param DbProcessRunner $dbRunner + * @param LoggerInterface $logger + */ public function __construct( VCenter $vCenter, VsphereApi $api, @@ -121,20 +127,32 @@ public function __construct( $this->dbRunner = $dbRunner; } - protected function removeVCenterOnlyTasks() + /** + * @return void + */ + protected function removeVCenterOnlyTasks(): void { $this->normalTasks = array_filter($this->normalTasks, function ($task) { return $task !== StoragePodSyncTask::class; }); } - public function start(LoopInterface $loop) + /** + * @param LoopInterface $loop + * + * @return PromiseInterface + */ + public function start(LoopInterface $loop): PromiseInterface { $this->loop = $loop; + return $this->initialize(); } - public function stop() + /** + * @return PromiseInterface + */ + public function stop(): PromiseInterface { $this->ready = false; foreach ($this->timers as $timer) { @@ -149,7 +167,10 @@ public function stop() return resolve(null); } - protected function initialize() + /** + * @return PromiseInterface + */ + protected function initialize(): PromiseInterface { return $this->prepareSyncResultHandler()->then(function () { return $this->prepareEventPolling(); @@ -162,7 +183,10 @@ protected function initialize() }); } - protected function scheduleTasks() + /** + * @return void + */ + protected function scheduleTasks(): void { $this->timers[] = $this->loop->addPeriodicTimer(600, function () { // There might be new CustomValue definitions @@ -192,7 +216,10 @@ protected function scheduleTasks() }); } - protected function refreshOutdatedDatastores() + /** + * @return void + */ + protected function refreshOutdatedDatastores(): void { $idx = VmDatastoreUsageSyncStore::class; $label = 'Refresh outdated VMs'; @@ -220,14 +247,22 @@ protected function refreshOutdatedDatastores() } } - protected function runTasks(array $tasks) + /** + * @param array $tasks + * + * @return void + */ + protected function runTasks(array $tasks): void { foreach ($tasks as $task) { $this->runTask(new $task()); } } - protected function runAllTasks() + /** + * @return void + */ + protected function runAllTasks(): void { $this->runTasks(array_merge($this->fastTasks, $this->normalTasks, $this->slowTasks)); $this->restApi->requireSession()->then(function () { @@ -235,7 +270,12 @@ protected function runAllTasks() }); } - protected function runTask(SyncTask $task) + /** + * @param SyncTask $task + * + * @return void + */ + protected function runTask(SyncTask $task): void { $label = $task->getLabel(); $idx = get_class($task); @@ -274,7 +314,7 @@ protected function runTask(SyncTask $task) 'result' => $result, 'taskLabel' => $task->getLabel(), 'storeClass' => $task->getSyncStoreClass(), - 'objectClass' => $task->getObjectClass(), + 'objectClass' => $task->getObjectClass() ])->then(function ($stats) use ($idx, $label) { $stats = SyncStats::fromSerialization($stats); if ($stats->hasChanges()) { @@ -298,7 +338,10 @@ protected function runTask(SyncTask $task) }); } - protected function prepareEventPolling() + /** + * @return PromiseInterface + */ + protected function prepareEventPolling(): PromiseInterface { return $this->dbRunner->request('db.getLastEventTimeStamp', [ 'vCenterId' => $this->vCenter->get('id') @@ -310,9 +353,9 @@ protected function prepareEventPolling() /** * Refreshes the custom fields map in the DB process * - * @return \React\Promise\PromiseInterface + * @return PromiseInterface */ - protected function prepareSyncResultHandler() + protected function prepareSyncResultHandler(): PromiseInterface { return $this->api->fetchCustomFieldsManager()->then(function (?CustomFieldsManager $manager = null) { if ($manager === null) { @@ -321,7 +364,7 @@ protected function prepareSyncResultHandler() return $this->dbRunner->request('db.setCustomFieldsMap', [ 'vCenterId' => $this->vCenter->get('id'), - 'map' => $manager->requireMap(), + 'map' => $manager->requireMap() ]); }); } diff --git a/library/Vspheredb/Daemon/PerfDataSync.php b/library/Vspheredb/Daemon/PerfDataSync.php index e2835cfe..cdb3cea3 100644 --- a/library/Vspheredb/Daemon/PerfDataSync.php +++ b/library/Vspheredb/Daemon/PerfDataSync.php @@ -35,36 +35,39 @@ use Ramsey\Uuid\UuidInterface; use React\EventLoop\LoopInterface; use React\EventLoop\TimerInterface; +use React\Promise\PromiseInterface; use stdClass; use Throwable; +use Zend_Db_Adapter_Abstract; use function React\Promise\resolve; class PerfDataSync implements DaemonTask { - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; - /** @var VsphereApi */ - protected $api; + protected VsphereApi $api; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var CurlAsync */ - protected $curl; + protected CurlAsync $curl; - /** @var ChunkedInfluxDbWriter */ - protected $influxDbWriter; + protected ?ChunkedInfluxDbWriter $influxDbWriter = null; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; /** @var TimerInterface[] */ - protected $timers = []; + protected array $timers = []; - protected $loadingWriterConfig = false; + protected bool $loadingWriterConfig = false; + /** + * @param VCenter $vCenter + * @param VsphereApi $api + * @param CurlAsync $curl + * @param LoopInterface $loop + * @param LoggerInterface $logger + */ public function __construct( VCenter $vCenter, VsphereApi $api, @@ -79,7 +82,12 @@ public function __construct( $this->logger = $logger; } - public function start(LoopInterface $loop) + /** + * @param LoopInterface $loop + * + * @return PromiseInterface + */ + public function start(LoopInterface $loop): PromiseInterface { $this->loop = $loop; $loop->futureTick(function () { @@ -89,7 +97,10 @@ public function start(LoopInterface $loop) return resolve(null); } - public function stop() + /** + * @return PromiseInterface + */ + public function stop(): PromiseInterface { foreach ($this->timers as $timer) { $this->loop->cancelTimer($timer); @@ -99,7 +110,10 @@ public function stop() return resolve(null); } - protected function loadWriterConfig() + /** + * @return PromiseInterface + */ + protected function loadWriterConfig(): PromiseInterface { if ($this->loadingWriterConfig) { return resolve(null); @@ -109,6 +123,7 @@ protected function loadWriterConfig() if (! $loader) { $this->stopRunningInfluxDbInstances(); $this->loadingWriterConfig = false; + return resolve(null); } return $loader->then(function (?ChunkedInfluxDbWriter $writer) { @@ -129,15 +144,19 @@ protected function loadWriterConfig() }); } - protected function stopRunningInfluxDbInstances() + /** + * @return void + */ + protected function stopRunningInfluxDbInstances(): void { - if ($this->influxDbWriter) { - $this->influxDbWriter->stop(); - $this->influxDbWriter = null; - } + $this->influxDbWriter?->stop(); + $this->influxDbWriter = null; } - protected function initialize() + /** + * @return void + */ + protected function initialize(): void { $this->syncCounterInfo()->then(function () { $this->loadWriterConfig(); @@ -149,15 +168,17 @@ protected function initialize() /** * @param $spec - * @return \React\Promise\PromiseInterface + * + * @return PromiseInterface */ - protected function queryPerf($spec) + protected function queryPerf($spec): PromiseInterface { return $this->api->callOnServiceInstanceObject('perfManager', 'QueryPerf', [ 'querySpec' => $spec ])->then(function ($result) { if (!isset($result->returnval)) { $this->logger->warning('Got no returnval when fetching performance data'); + return []; } @@ -165,22 +186,33 @@ protected function queryPerf($spec) }); } + /** + * @param Zend_Db_Adapter_Abstract $db + * @param UuidInterface $vCenterUuid + * @param PerformanceSet $set + * @param CounterLookup $counterLookup + * @param ?int $count + * + * @return void + */ protected function fetchPerf( - $db, + Zend_Db_Adapter_Abstract $db, UuidInterface $vCenterUuid, PerformanceSet $set, CounterLookup $counterLookup, - $count - ) { + ?int $count + ): void { $tags = $counterLookup->fetchTags($vCenterUuid); $counterMap = CounterMap::fetchCounters($db, $set, $vCenterUuid); if (empty($counterMap)) { $this->logger->notice('Got no counters, nothing to do'); + return; } $instances = $counterLookup->fetchRequiredMetricInstances($vCenterUuid); if (empty($instances)) { $this->logger->notice('Got no instances to fetch, nothing to do'); + return; } $spec = PerformanceQuerySpecHelper::prepareQuerySpec( @@ -191,6 +223,7 @@ protected function fetchPerf( ); if ($this->influxDbWriter === null) { $this->logger->notice('No more InfluxDB writer available, nothing to do'); + return; } @@ -214,7 +247,12 @@ protected function fetchPerf( }); } - protected function sync($count = null) + /** + * @param ?int $count + * + * @return void + */ + protected function sync(?int $count = null): void { $db = $this->vCenter->getConnection()->getDbAdapter(); $uuid = Uuid::fromBytes($this->vCenter->getUuid()); @@ -244,7 +282,10 @@ protected function sync($count = null) $this->fetchPerf($db, $uuid, $set, $counterLookup, $count); } - protected function scheduleTasks() + /** + * @return void + */ + protected function scheduleTasks(): void { $this->timers[] = $this->loop->addPeriodicTimer(120, function () { $this->loadWriterConfig()->then(function () { @@ -259,17 +300,26 @@ protected function scheduleTasks() }); } - protected function syncCounterInfo() + /** + * @return PromiseInterface + */ + protected function syncCounterInfo(): PromiseInterface { return $this->api->getServiceInstance()->then(function (ServiceContent $content) { return $this->api->fetchSingleObject($content->perfManager); })->then(function ($result) { $this->storeCounterInfo($result); + return resolve(null); }); } - protected function storeCounterInfo($result) + /** + * @param mixed $result + * + * @return void + */ + protected function storeCounterInfo(mixed $result): void { $store = new PerfCounterInfoSyncStore( $this->vCenter->getConnection()->getDbAdapter(), diff --git a/library/Vspheredb/Daemon/RemoteApi.php b/library/Vspheredb/Daemon/RemoteApi.php index 4f1883dd..fc57b908 100644 --- a/library/Vspheredb/Daemon/RemoteApi.php +++ b/library/Vspheredb/Daemon/RemoteApi.php @@ -14,14 +14,15 @@ use gipfl\Protocol\NetString\StreamWrapper; use gipfl\Socket\UnixSocketInspection; use gipfl\Socket\UnixSocketPeer; -use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceDbProxy; -use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceProcess; use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceCurl; +use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceDbProxy; use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceInfluxDb; use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceLogger; +use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceProcess; use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceSystem; use Icinga\Module\Vspheredb\Daemon\RpcNamespace\RpcNamespaceVsphere; use Icinga\Module\Vspheredb\Polling\ApiConnectionHandler; +use InvalidArgumentException; use Psr\Log\LoggerInterface; use React\EventLoop\LoopInterface; use React\Socket\ConnectionInterface; @@ -33,24 +34,24 @@ class RemoteApi implements EventEmitterInterface { use EventEmitterTrait; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - /** @var ControlSocket */ - protected $controlSocket; + protected ?ControlSocket $controlSocket = null; - /** @var ApiConnectionHandler */ - protected $apiConnectionHandler; + protected ApiConnectionHandler $apiConnectionHandler; - /** @var CurlAsync */ - protected $curl; + protected CurlAsync $curl; - /** @var RpcNamespaceDbProxy */ - protected $rpcNamespaceRpcProxy; + protected RpcNamespaceDbProxy $rpcNamespaceRpcProxy; + /** + * @param ApiConnectionHandler $apiConnectionHandler + * @param CurlAsync $curl + * @param LoopInterface $loop + * @param LoggerInterface $logger + */ public function __construct( ApiConnectionHandler $apiConnectionHandler, CurlAsync $curl, @@ -64,21 +65,37 @@ public function __construct( $this->rpcNamespaceRpcProxy = new RpcNamespaceDbProxy('db.'); } - public function run($socketPath, LoopInterface $loop) + /** + * @param string $socketPath + * @param LoopInterface $loop + * + * @return void + */ + public function run(string $socketPath, LoopInterface $loop): void { $this->loop = $loop; $this->initializeControlSocket($socketPath); } - public function setDbProcessRunner(?DbProcessRunner $dbProcessRunner) + /** + * @param ?DbProcessRunner $dbProcessRunner + * + * @return void + */ + public function setDbProcessRunner(?DbProcessRunner $dbProcessRunner): void { $this->rpcNamespaceRpcProxy->setDbProcessRunner($dbProcessRunner); } - protected function initializeControlSocket($path) + /** + * @param string $path + * + * @return void + */ + protected function initializeControlSocket(string $path): void { if (empty($path)) { - throw new \InvalidArgumentException('Control socket path expected, got none'); + throw new InvalidArgumentException('Control socket path expected, got none'); } $this->logger->info("[socket] launching control socket in $path"); $socket = new ControlSocket($path); @@ -87,7 +104,12 @@ protected function initializeControlSocket($path) $this->controlSocket = $socket; } - protected function isAllowed(UnixSocketPeer $peer) + /** + * @param UnixSocketPeer $peer + * + * @return bool + */ + protected function isAllowed(UnixSocketPeer $peer): bool { if ($peer->getUid() === 0) { return true; @@ -105,7 +127,12 @@ protected function isAllowed(UnixSocketPeer $peer) return in_array($myGid, array_map('intval', explode(' ', shell_exec("id -G $uid")))); } - protected function addSocketEventHandlers(ControlSocket $socket) + /** + * @param ControlSocket $socket + * + * @return void + */ + protected function addSocketEventHandlers(ControlSocket $socket): void { $socket->on('connection', function (ConnectionInterface $connection) { $jsonRpc = new JsonRpcConnection(new StreamWrapper($connection)); diff --git a/library/Vspheredb/Daemon/RemoteClient.php b/library/Vspheredb/Daemon/RemoteClient.php index 33b77077..2b3ad8f8 100644 --- a/library/Vspheredb/Daemon/RemoteClient.php +++ b/library/Vspheredb/Daemon/RemoteClient.php @@ -5,6 +5,7 @@ use gipfl\Protocol\JsonRpc\JsonRpcConnection; use gipfl\Protocol\NetString\StreamWrapper; use React\EventLoop\LoopInterface; +use React\Promise\PromiseInterface; use React\Socket\ConnectionInterface; use React\Socket\UnixConnector; @@ -12,50 +13,66 @@ class RemoteClient { - protected $path; + protected string $path; - /** @var JsonRpcConnection */ - protected $connection; + protected ?JsonRpcConnection $connection = null; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - protected $pendingConnection; + protected ?PromiseInterface $pendingConnection = null; - public function __construct($path, LoopInterface $loop) + /** + * @param string $path + * @param LoopInterface $loop + */ + public function __construct(string $path, LoopInterface $loop) { $this->path = $path; $this->loop = $loop; } - public function request($method, $params = null) + /** + * @param string $method + * @param ?array $params + * + * @return PromiseInterface + */ + public function request(string $method, ?array $params = null): PromiseInterface { return $this->connection()->then(function (JsonRpcConnection $connection) use ($method, $params) { return $connection->request($method, $params); }); } - public function notify($method, $params = null) + /** + * @param string $method + * @param ?array $params + * + * @return PromiseInterface + */ + public function notify(string $method, ?array $params = null): PromiseInterface { return $this->connection()->then(function (JsonRpcConnection $connection) use ($method, $params) { $connection->notification($method, $params); }); } - protected function connection() + /** + * @return PromiseInterface + */ + protected function connection(): PromiseInterface { if ($this->connection === null) { - if ($this->pendingConnection === null) { - return $this->connect(); - } else { - return $this->pendingConnection; - } - } else { - return resolve($this->connection); + return $this->pendingConnection ?? $this->connect(); } + + return resolve($this->connection); } - protected function connect() + /** + * @return PromiseInterface + */ + protected function connect(): PromiseInterface { $connector = new UnixConnector($this->loop); $connected = function (ConnectionInterface $connection) { diff --git a/library/Vspheredb/Daemon/RpcNamespace/DbRunner.php b/library/Vspheredb/Daemon/RpcNamespace/DbRunner.php index 53be1ce9..1f6c78ec 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/DbRunner.php +++ b/library/Vspheredb/Daemon/RpcNamespace/DbRunner.php @@ -5,6 +5,7 @@ use Exception; use gipfl\Cli\Process; use Icinga\Data\ConfigObject; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Application\MemoryLimit; use Icinga\Module\Vspheredb\Daemon\DbCleanup; use Icinga\Module\Vspheredb\Db; @@ -20,6 +21,8 @@ use React\Promise\Deferred; use React\Promise\PromiseInterface; use RuntimeException; +use Throwable; +use Zend_Db_Adapter_Abstract; use function React\Promise\reject; use function React\Promise\resolve; @@ -29,27 +32,27 @@ */ class DbRunner { - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var Db */ - protected $connection; + protected ?Db $connection = null; - protected $db; + protected ?Zend_Db_Adapter_Abstract $db = null; - /** @var ?DbCleanup */ - protected $runningVcenterDeletion = null; + protected ?VCenterCleanup $runningVcenterDeletion = null; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - protected $vCenters = []; + protected array $vCenters = []; /** * @var array vCenterId -> [ SyncStoreClassName => SyncStore ] */ - protected $vCenterSyncStores = []; + protected array $vCenterSyncStores = []; + /** + * @param LoggerInterface $logger + * @param LoopInterface $loop + */ public function __construct(LoggerInterface $logger, LoopInterface $loop) { MemoryLimit::raiseTo('1024M'); @@ -68,7 +71,7 @@ public function __construct(LoggerInterface $logger, LoopInterface $loop) if ($this->connection) { try { $this->refreshMonitoringRuleProblemsRequest(); - } catch (\Throwable $e) { + } catch (Throwable $e) { $this->logger->error($e->getMessage()); } } @@ -77,10 +80,12 @@ public function __construct(LoggerInterface $logger, LoopInterface $loop) /** * @param object $config + * * @return PromiseInterface + * * @throws Exception */ - public function setDbConfigRequest($config) + public function setDbConfigRequest(object $config): PromiseInterface { try { $this->vCenters = []; @@ -111,7 +116,10 @@ public function setDbConfigRequest($config) } } - protected function setProcessReadyTitle() + /** + * @return void + */ + protected function setProcessReadyTitle(): void { Process::setTitle('Icinga::vSphereDB::DB::connected'); } @@ -119,25 +127,27 @@ protected function setProcessReadyTitle() /** * @return bool */ - public function runDbCleanupRequest() + public function runDbCleanupRequest(): bool { $this->requireCleanup()->runForStartup(); + return true; } /** * @return bool */ - public function clearDbConfigRequest() + public function clearDbConfigRequest(): bool { $this->disconnect(); + return true; } /** * @return bool */ - public function hasPendingMigrationsRequest() + public function hasPendingMigrationsRequest(): bool { if ($this->connection === null) { throw new RuntimeException('Unable to determine migration status, have no DB connection'); @@ -167,10 +177,12 @@ public function setCustomFieldsMapRequest(int $vCenterId, array $map): bool /** * @param int $vCenterId + * * @return int - * @throws \Icinga\Exception\NotFoundError + * + * @throws NotFoundError */ - public function getLastEventTimeStampRequest($vCenterId) + public function getLastEventTimeStampRequest(int $vCenterId): int { return VmEventHistorySyncStore::selectLast( $this->db, @@ -185,17 +197,23 @@ public function getLastEventTimeStampRequest($vCenterId) * @param string $taskLabel * @param string $storeClass * @param string $objectClass + * * @return SyncStats */ - public function processSyncTaskResultRequest($vCenterId, $result, $taskLabel, $storeClass, $objectClass) - { + public function processSyncTaskResultRequest( + int $vCenterId, + array $result, + string $taskLabel, + string $storeClass, + string $objectClass + ): SyncStats { Process::setTitle('Icinga::vSphereDB::DB::Storing ' . $taskLabel); $stats = new SyncStats($taskLabel); try { $this->requireSyncStoreForVCenterInstance($vCenterId, $storeClass) ->store($result, $objectClass, $stats); - } catch (\Throwable $e) { + } catch (Throwable $e) { $this->logger->error(sprintf( 'Task %s failed. %s: %s (%d)', $taskLabel, @@ -209,15 +227,20 @@ public function processSyncTaskResultRequest($vCenterId, $result, $taskLabel, $s return $stats; } - public function refreshMonitoringRuleProblemsRequest() + /** + * @return bool + */ + public function refreshMonitoringRuleProblemsRequest(): bool { if ($this->connection === null) { $this->logger->warning('Not refreshing Rule problems, DB is not ready'); + return false; } if (Db::migrationsForDb($this->connection)->hasPendingMigrations()) { $this->logger->warning('Not refreshing Rule problems, DB is not ready'); + return false; } @@ -229,26 +252,26 @@ public function refreshMonitoringRuleProblemsRequest() $this->logger->debug(sprintf('Refreshing Monitoring Rule problems took %.2Fs', $duration)); return true; - } catch (\Throwable $e) { + } catch (Throwable $e) { $this->logger->error('Refreshing Rule Problems failed: ' . $e->getMessage()); + return false; } } /** * @param int $vCenterId + * * @return bool */ - public function deleteVcenterRequest($vCenterId) + public function deleteVcenterRequest(int $vCenterId): bool { $this->logger->notice('Got db.deleteVcenter for id=' . $vCenterId); if ($this->connection === null) { throw new RuntimeException('Unable to remove vCenter, have no DB connection'); } if ($this->runningVcenterDeletion !== null) { - throw new RuntimeException( - 'Unable to remove vCenter, a cleanup is in progress' - ); + throw new RuntimeException('Unable to remove vCenter, a cleanup is in progress'); } Process::setTitle('Icinga::vSphereDB::DB::deleteVcenter ' . $vCenterId); @@ -269,7 +292,8 @@ public function deleteVcenterRequest($vCenterId) * @param string $class * * @return SyncStore - * @throws \Icinga\Exception\NotFoundError + * + * @throws NotFoundError */ protected function requireSyncStoreForVCenterInstance(int $vCenterId, string $class): SyncStore { @@ -292,7 +316,8 @@ protected function requireSyncStoreForVCenterInstance(int $vCenterId, string $cl * @param int $id * * @return VCenter - * @throws \Icinga\Exception\NotFoundError + * + * @throws NotFoundError */ protected function requireVCenter(int $id): VCenter { @@ -303,12 +328,17 @@ protected function requireVCenter(int $id): VCenter return $this->vCenters[$id]; } - protected function connect($config) + /** + * @param object $config + * + * @return void + */ + protected function connect(object $config): void { $this->logger->debug('Connecting to DB'); try { $this->disconnect(); - } catch (Exception $e) { + } catch (Exception) { // Ignore disconnection errors } $this->connection = new Db(new ConfigObject((array) $config)); @@ -316,7 +346,10 @@ protected function connect($config) $this->db->getConnection(); } - protected function disconnect() + /** + * @return void + */ + protected function disconnect(): void { if ($this->connection) { $this->connection->getDbAdapter()->closeConnection(); @@ -325,17 +358,21 @@ protected function disconnect() } } - protected function requireCleanup() + /** + * @return DbCleanup + */ + protected function requireCleanup(): DbCleanup { if ($this->connection === null) { throw new RuntimeException('Cannot run DB cleanup w/o DB connection'); } $c = new DbCleanup($this->connection->getDbAdapter(), $this->logger); Process::setTitle('Icinga::vSphereDB::DB::cleanup'); + return $c; } - protected function applyMigrations() + protected function applyMigrations(): PromiseInterface { try { $migrations = Db::migrationsForDb($this->connection); diff --git a/library/Vspheredb/Daemon/RpcNamespace/LogProxy.php b/library/Vspheredb/Daemon/RpcNamespace/LogProxy.php index c29088af..05ee5edb 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/LogProxy.php +++ b/library/Vspheredb/Daemon/RpcNamespace/LogProxy.php @@ -6,17 +6,24 @@ class LogProxy { - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - protected $prefix; + protected string $prefix = ''; + /** + * @param LoggerInterface $logger + */ public function __construct(LoggerInterface $logger) { $this->logger = $logger; } - public function setPrefix($prefix) + /** + * @param string $prefix + * + * @return $this + */ + public function setPrefix(string $prefix): static { $this->prefix = $prefix; @@ -27,8 +34,10 @@ public function setPrefix($prefix) * @param string $level * @param string $message * @param array $context + * + * @return void */ - public function logNotification($level, $message, $context = []) + public function logNotification(string $level, string $message, array $context = []): void { $this->logger->log($level, $this->prefix . $message, $context); } diff --git a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceCurl.php b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceCurl.php index 8a324abf..30df6fe9 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceCurl.php +++ b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceCurl.php @@ -6,21 +6,21 @@ class RpcNamespaceCurl { - /** @var CurlAsync */ - protected $curl; + protected CurlAsync $curl; + /** + * @param CurlAsync $curl + */ public function __construct(CurlAsync $curl) { $this->curl = $curl; } - public function getPendingConnectionsRequest() + /** + * @return array + */ + public function getPendingConnectionsRequest(): array { - $handles = []; - foreach ($this->curl->getPendingCurlHandles() as $idx => $curl) { - $handles[$idx] = curl_getinfo($curl); - } - - return $handles; + return array_map(fn ($curl) => curl_getinfo($curl), $this->curl->getPendingCurlHandles()); } } diff --git a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceDbProxy.php b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceDbProxy.php index 2d63b7e8..5abe53dc 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceDbProxy.php +++ b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceDbProxy.php @@ -3,35 +3,49 @@ namespace Icinga\Module\Vspheredb\Daemon\RpcNamespace; use Icinga\Module\Vspheredb\Daemon\DbProcessRunner; +use React\Promise\PromiseInterface; +use RuntimeException; class RpcNamespaceDbProxy { - /** @var ?DbProcessRunner */ - protected $runner; + protected ?DbProcessRunner $runner = null; - /** @var string */ - protected $prefix; + protected string $prefix; + /** + * @param string $prefix + */ public function __construct(string $prefix) { $this->prefix = $prefix; } - public function setDbProcessRunner(?DbProcessRunner $runner) + /** + * @param ?DbProcessRunner $runner + * + * @return void + */ + public function setDbProcessRunner(?DbProcessRunner $runner): void { $this->runner = $runner; } - public function __call($method, $params) + /** + * @param string $method + * @param array $params + * + * @return PromiseInterface + */ + public function __call(string $method, array $params) { - if (preg_match('/Request$/', $method)) { + if (str_ends_with($method, 'Request')) { if ($this->runner === null) { - throw new \RuntimeException('DB runner is not ready'); + throw new RuntimeException('DB runner is not ready'); } return $this->runner->request($this->prefix . substr($method, 0, -7), $params); } - throw new \RuntimeException('Got no such method: ' . $method); + throw new RuntimeException('Got no such method: ' . $method); } } diff --git a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceInfluxDb.php b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceInfluxDb.php index 9a95186a..c1121b04 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceInfluxDb.php +++ b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceInfluxDb.php @@ -9,20 +9,23 @@ use gipfl\InfluxDb\InfluxDbConnectionV2; use Psr\Log\LoggerInterface; use React\EventLoop\LoopInterface; +use React\Promise\PromiseInterface; use function React\Promise\resolve; class RpcNamespaceInfluxDb { - /** - * @var LoopInterface - */ - protected $loop; + protected LoopInterface $loop; - protected $logger; + protected LoggerInterface $logger; - protected $curl; + protected CurlAsync $curl; + /** + * @param CurlAsync $curl + * @param LoopInterface $loop + * @param LoggerInterface $logger + */ public function __construct(CurlAsync $curl, LoopInterface $loop, LoggerInterface $logger) { $this->curl = $curl; @@ -32,8 +35,10 @@ public function __construct(CurlAsync $curl, LoopInterface $loop, LoggerInterfac /** * @param string $baseUrl Base URL + * + * @return PromiseInterface */ - public function discoverVersionRequest($baseUrl) + public function discoverVersionRequest(string $baseUrl): PromiseInterface { return $this->connect($baseUrl)->then(function ($connection) { return $connection->getVersion(); @@ -42,12 +47,18 @@ public function discoverVersionRequest($baseUrl) /** * @param string $baseUrl Base URL - * @param string $apiVersion v1/v2 - * @param string $username username / organization - * @param string $password password / token + * @param ?string $apiVersion v1/v2 + * @param ?string $username username / organization + * @param ?string $password password / token + * + * @return PromiseInterface */ - public function testConnectionRequest($baseUrl, $apiVersion = null, $username = null, $password = null) - { + public function testConnectionRequest( + string $baseUrl, + ?string $apiVersion = null, + ?string $username = null, + ?string $password = null + ): PromiseInterface { return $this->listDatabasesRequest($baseUrl, $apiVersion, $username, $password)->then(function () { return true; }); @@ -55,12 +66,18 @@ public function testConnectionRequest($baseUrl, $apiVersion = null, $username = /** * @param string $baseUrl Base URL - * @param string $apiVersion v1/v2 - * @param string $username username / organization - * @param string $password password / token + * @param ?string $apiVersion v1/v2 + * @param ?string $username username / organization + * @param ?string $password password / token + * + * @return PromiseInterface */ - public function listDatabasesRequest($baseUrl, $apiVersion = null, $username = null, $password = null) - { + public function listDatabasesRequest( + string $baseUrl, + ?string $apiVersion = null, + ?string $username = null, + ?string $password = null + ): PromiseInterface { return $this->connect($baseUrl, $apiVersion, $username, $password)->then(function ($connection) { /** @var InfluxDbConnectionV1|InfluxDbConnectionV2 $connection */ return $connection->listDatabases(); @@ -73,25 +90,42 @@ public function listDatabasesRequest($baseUrl, $apiVersion = null, $username = n * @param string $apiVersion v1/v2 * @param string $username username / organization * @param string $password password / token + * + * @return PromiseInterface */ - public function createDatabaseRequest($dbName, $baseUrl, $apiVersion, $username, $password) - { + public function createDatabaseRequest( + string $dbName, + string $baseUrl, + string $apiVersion, + string $username, + string $password + ): PromiseInterface { return $this->connect($baseUrl, $apiVersion, $username, $password)->then(function ($connection) use ($dbName) { /** @var InfluxDbConnection $connection */ $this->logger->info("CREATING $dbName"); + return $connection->createDatabase($dbName); }); } - protected function connect($baseUrl, $apiVersion = null, $username = null, $password = null) - { - switch ($apiVersion) { - case 'v1': - return resolve(new InfluxDbConnectionV1($this->curl, $baseUrl, $username, $password)); - case 'v2': - return resolve(new InfluxDbConnectionV2($this->curl, $baseUrl, $username, $password)); - } - - return InfluxDbConnectionFactory::create($this->curl, $baseUrl, $username, $password); + /** + * @param string $baseUrl + * @param ?string $apiVersion + * @param ?string $username + * @param ?string $password + * + * @return PromiseInterface + */ + protected function connect( + string $baseUrl, + ?string $apiVersion = null, + ?string $username = null, + ?string $password = null + ): PromiseInterface { + return match ($apiVersion) { + 'v1' => resolve(new InfluxDbConnectionV1($this->curl, $baseUrl, $username, $password)), + 'v2' => resolve(new InfluxDbConnectionV2($this->curl, $baseUrl, $username, $password)), + default => InfluxDbConnectionFactory::create($this->curl, $baseUrl, $username, $password), + }; } } diff --git a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceLogger.php b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceLogger.php index a4da4941..5ed2dc20 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceLogger.php +++ b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceLogger.php @@ -8,9 +8,11 @@ class RpcNamespaceLogger { - /** @var Logger */ - protected $logger; + protected Logger $logger; + /** + * @param Logger $logger + */ public function __construct(Logger $logger) { $this->logger = $logger; @@ -19,16 +21,17 @@ public function __construct(Logger $logger) /** * @return string */ - public function getLogLevelRequest() + public function getLogLevelRequest(): string { return LogLevel::mapNumericToName($this->getCurrentNumericLogLevel()); } /** * @param string $level + * * @return bool */ - public function setLogLevelRequest($level) + public function setLogLevelRequest(string $level): bool { $formerLevel = $this->getCurrentNumericLogLevel(); $numericLevel = LogLevel::mapNameToNumeric($level); @@ -56,7 +59,10 @@ public function setLogLevelRequest($level) return true; } - protected function getCurrentNumericLogLevel() + /** + * @return int + */ + protected function getCurrentNumericLogLevel(): int { $level = LogLevel::LEVEL_DEBUG; foreach ($this->logger->getFilters() as $filter) { diff --git a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceProcess.php b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceProcess.php index c9eb8920..e88f0e78 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceProcess.php +++ b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceProcess.php @@ -12,9 +12,11 @@ class RpcNamespaceProcess implements EventEmitterInterface public const ON_RESTART = 'restart'; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; + /** + * @param LoopInterface $loop + */ public function __construct(LoopInterface $loop) { $this->loop = $loop; @@ -33,7 +35,7 @@ protected function prepareProcessInfo(Daemon $daemon) return (object) [ 'state' => $this->daemon->getProcessState()->getInfo(), - 'details' => (object) $details, + 'details' => (object) $details ]; } */ @@ -41,7 +43,7 @@ protected function prepareProcessInfo(Daemon $daemon) /** * @return bool */ - public function restartRequest() + public function restartRequest(): bool { // Grant some time to ship the response $this->loop->addTimer(0.1, function () { diff --git a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceSystem.php b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceSystem.php index 2b1b0d64..a2639d14 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceSystem.php +++ b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceSystem.php @@ -10,7 +10,7 @@ class RpcNamespaceSystem /** * @return object */ - public function cpuCountersRequest() + public function cpuCountersRequest(): object { return (object) Cpu::getCounters(); } @@ -18,7 +18,7 @@ public function cpuCountersRequest() /** * @return object */ - public function interfaceCountersRequest() + public function interfaceCountersRequest(): object { return (object) Network::getInterfaceCounters(); } diff --git a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceVsphere.php b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceVsphere.php index 576f0e49..f0b66c5d 100644 --- a/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceVsphere.php +++ b/library/Vspheredb/Daemon/RpcNamespace/RpcNamespaceVsphere.php @@ -8,9 +8,11 @@ class RpcNamespaceVsphere { - /** @var ApiConnectionHandler */ - protected $apiConnectionHandler; + protected ApiConnectionHandler $apiConnectionHandler; + /** + * @param ApiConnectionHandler $apiConnectionHandler + */ public function __construct(ApiConnectionHandler $apiConnectionHandler) { $this->apiConnectionHandler = $apiConnectionHandler; @@ -20,6 +22,7 @@ public function __construct(ApiConnectionHandler $apiConnectionHandler) * Hint: Full qualified reference is necessary for RPC type check * * @param \Icinga\Module\Vspheredb\Polling\ServerSet $servers + * * @return bool */ public function setServersRequest(ServerSet $servers): bool diff --git a/library/Vspheredb/Daemon/StateMachine.php b/library/Vspheredb/Daemon/StateMachine.php index b023e1a0..2e06c0ee 100644 --- a/library/Vspheredb/Daemon/StateMachine.php +++ b/library/Vspheredb/Daemon/StateMachine.php @@ -6,16 +6,20 @@ trait StateMachine { - /** @var string */ - private $currentState; + private ?string $currentState = null; /** @var array [fromState][toState] = [callback, ...] */ - private $allowedTransitions = []; + private array $allowedTransitions = []; /** @var array [state] = [callback, ...] */ - private $onState = []; + private array $onState = []; - public function initializeStateMachine($initialState) + /** + * @param string $initialState + * + * @return void + */ + public function initializeStateMachine(string $initialState): void { if ($this->currentState !== null) { throw new RuntimeException('StateMachine has already been initialized'); diff --git a/library/Vspheredb/Daemon/VsphereDbDaemon.php b/library/Vspheredb/Daemon/VsphereDbDaemon.php index ab6c057f..9b3aa731 100644 --- a/library/Vspheredb/Daemon/VsphereDbDaemon.php +++ b/library/Vspheredb/Daemon/VsphereDbDaemon.php @@ -8,7 +8,6 @@ use gipfl\Cli\Process; use gipfl\Curl\CurlAsync; use gipfl\LinuxHealth\Memory; -use gipfl\Log\Logger; use gipfl\Log\PrefixLogger; use gipfl\ReactUtils\RetryUnless; use gipfl\SimpleDaemon\DaemonState; @@ -37,8 +36,11 @@ use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use React\EventLoop\LoopInterface; +use React\Promise\PromiseInterface; use React\Stream\Util as StreamUtil; use RuntimeException; +use Zend_Db_Adapter_Abstract; +use Zend_Db_Adapter_Exception; use function React\Promise\resolve; @@ -60,59 +62,52 @@ class VsphereDbDaemon implements DaemonTask, SystemdAwareTask, LoggerAwareInterf public const STATE_FAILED = 'failed'; public const STATE_IDLE = 'idle'; - /** @var LoopInterface */ - private $loop; + private ?LoopInterface $loop = null; - /** @var array|null */ - protected $dbConfig; + protected ?array $dbConfig = null; - /** @var Db */ - protected $connection; + protected ?Db $connection = null; - /** @var object */ - protected $processInfo; + protected ?object $processInfo = null; - protected $delayOnFailed = 5; + protected int $delayOnFailed = 5; - /** @var NotifySystemD|boolean */ - protected $systemd; + protected ?NotifySystemD $systemd = null; - /** @var DbLogger */ - protected $dbLogger; + protected ?DbLogger $dbLogger = null; - /** @var RemoteApi */ - protected $remoteApi; + protected ?RemoteApi $remoteApi = null; - /** @var @var RemoteClient */ - protected $remoteClient; + protected ?RemoteClient $remoteClient = null; - /** @var CurlAsync */ - protected $curl; + protected ?CurlAsync $curl = null; - /** @var ApiConnectionHandler */ - protected $apiConnectionHandler; + protected ?ApiConnectionHandler $apiConnectionHandler = null; - /** @var DbProcessRunner */ - protected $dbRunner; + protected ?DbProcessRunner $dbRunner = null; - /** @var DaemonState */ - protected $daemonState; + protected ?DaemonState $daemonState = null; - protected $dbIsReady = false; + protected bool $dbIsReady = false; /** @var array [splhash(ApiConnection) => [ Task, ... ]] */ - protected $runningTasks = []; + protected array $runningTasks = []; - /** @var ConfigWatch */ - protected $configWatch; + protected ?ConfigWatch $configWatch = null; - protected $componentStates = [ + /** @var array */ + protected array $componentStates = [ self::COMPONENT_DB => self::STATE_STOPPED, self::COMPONENT_LOCALDB => self::STATE_STOPPED, - self::COMPONENT_API => self::STATE_STOPPED, + self::COMPONENT_API => self::STATE_STOPPED ]; - public function start(LoopInterface $loop) + /** + * @param LoopInterface $loop + * + * @return PromiseInterface + */ + public function start(LoopInterface $loop): PromiseInterface { MemoryLimit::raiseTo('1024M'); $this->loop = $loop; @@ -125,20 +120,25 @@ public function start(LoopInterface $loop) $this->initializeDbProcess(); $this->keepRefreshingServerConfig(); $this->daemonState->setState(self::STATE_IDLE); + return resolve(null); } - protected function initializeDaemonState() + /** + * @return DaemonState + */ + protected function initializeDaemonState(): DaemonState { $daemonState = new DaemonState(); $daemonState->setComponentStates($this->componentStates); $daemonState->on(DaemonState::ON_CHANGE, function ($processTitle, $statusSummary) use ($daemonState) { - if (strlen($statusSummary) === 0) { - Process::setTitle($processTitle); - } else { - Process::setTitle("$processTitle: $statusSummary"); + $title = $processTitle; + if (strlen($statusSummary !== 0)) { + $title .= ": $statusSummary"; } + Process::setTitle($title); + if ($this->systemd && strlen($statusSummary) > 0) { $this->systemd->setStatus($statusSummary); } @@ -156,14 +156,24 @@ protected function initializeDaemonState() return $daemonState; } - protected function setInitialDaemonState() + /** + * @return void + */ + protected function setInitialDaemonState(): void { $daemonState = $this->daemonState; $daemonState->setProcessTitle(self::PROCESS_NAME); $daemonState->setState(self::STATE_STARTING); } - protected function onComponentChange($component, $formerState, $currentState) + /** + * @param string $component + * @param string $formerState + * @param ?string $currentState + * + * @return void + */ + protected function onComponentChange(string $component, string $formerState, ?string $currentState): void { $this->logger->debug("[$component] component changed from $formerState to $currentState"); if ($this->daemonState->getComponentState($component) !== $currentState) { @@ -238,9 +248,7 @@ protected function onComponentChange($component, $formerState, $currentState) // Intentional fall-through: // no break case self::STATE_STOPPING: - if ($this->apiConnectionHandler) { - $this->apiConnectionHandler->stop(); - } + $this->apiConnectionHandler?->stop(); $this->stopAllApiTasks(); $this->setApiState(self::STATE_STOPPED); break; @@ -248,7 +256,12 @@ protected function onComponentChange($component, $formerState, $currentState) } } - protected function stopComponent($component) + /** + * @param string $component + * + * @return void + */ + protected function stopComponent(string $component): void { $state = $this->daemonState; if (! in_array($state->getComponentState($component), [self::STATE_STOPPED, self::STATE_STOPPING])) { @@ -257,32 +270,56 @@ protected function stopComponent($component) } } - protected function setDbState($state) + /** + * @param string $state + * + * @return void + */ + protected function setDbState(string $state): void { $this->daemonState->setComponentState(self::COMPONENT_DB, $state); } - protected function setLocalDbState($state) + /** + * @param string $state + * + * @return void + */ + protected function setLocalDbState(string $state): void { $this->daemonState->setComponentState(self::COMPONENT_LOCALDB, $state); } - protected function setApiState($state) + /** + * @param string $state + * + * @return void + */ + protected function setApiState(string $state): void { $this->daemonState->setComponentState(self::COMPONENT_API, $state); } - protected function getApiState() + /** + * @return ?string + */ + protected function getApiState(): ?string { return $this->daemonState->getComponentState(self::COMPONENT_API); } - protected function getLocalDbState() + /** + * @return ?string + */ + protected function getLocalDbState(): ?string { return $this->daemonState->getComponentState(self::COMPONENT_LOCALDB); } - protected function initializeDbProcess() + /** + * @return void + */ + protected function initializeDbProcess(): void { $dbRunner = new DbProcessRunner($this->logger); $this->setDbState(self::STATE_STARTING); @@ -295,27 +332,29 @@ protected function initializeDbProcess() }); $dbRunner->run($this->loop)->then(function () use ($dbRunner) { $this->dbRunner = $dbRunner; - if ($this->remoteApi) { - $this->remoteApi->setDbProcessRunner($dbRunner); - } + $this->remoteApi?->setDbProcessRunner($dbRunner); $this->loop->futureTick(function () { $this->setDbState(self::STATE_IDLE); }); }); } - protected function stopDbProcess() + /** + * @return void + */ + protected function stopDbProcess(): void { if ($this->dbRunner) { $this->dbRunner->stop(); $this->dbRunner = null; - if ($this->remoteApi) { - $this->remoteApi->setDbProcessRunner(null); - } + $this->remoteApi?->setDbProcessRunner(null); } } - protected function keepRefreshingServerConfig() + /** + * @return void + */ + protected function keepRefreshingServerConfig(): void { $refresh = function () { if ($this->daemonState->getComponentState(self::COMPONENT_LOCALDB) === self::STATE_READY) { @@ -326,20 +365,27 @@ protected function keepRefreshingServerConfig() $this->loop->futureTick($refresh); } - public function stop() + /** + * @return PromiseInterface + */ + public function stop(): PromiseInterface { try { $this->daemonState->setState(self::STATE_STOPPING); $this->logger->notice('Stopping vSphereDbDaemon'); $this->dbRunner->stop(); $this->eventuallyDisconnectFromDb(); - } catch (\Exception $e) { + } catch (Exception $e) { $this->logger->error('Failed to stop vSphereDbDaemon: ' . $e->getMessage()); } + return resolve(null); } - protected function detectProcessInfo() + /** + * @return void + */ + protected function detectProcessInfo(): void { $this->processInfo = (object) [ 'instance_uuid' => Uuid::uuid4()->getBytes(), @@ -347,11 +393,16 @@ protected function detectProcessInfo() 'pid' => posix_getpid(), 'fqdn' => Platform::getFqdn(), 'username' => Platform::getPhpUser(), - 'php_version' => Platform::getPhpVersion(), + 'php_version' => Platform::getPhpVersion() ]; } - protected function initializeDbLogger(LoggerInterface $logger) + /** + * @param LoggerInterface $logger + * + * @return void + */ + protected function initializeDbLogger(LoggerInterface $logger): void { // TODO: ProcessInfo! $this->dbLogger = new DbLogger( @@ -366,7 +417,14 @@ protected function initializeDbLogger(LoggerInterface $logger) $logger->addWriter($this->dbLogger); } - protected function onNewConnectedServer(ServerInfo $server, AboutInfo $about, UuidInterface $uuid) + /** + * @param ServerInfo $server + * @param AboutInfo $about + * @param UuidInterface $uuid + * + * @return void + */ + protected function onNewConnectedServer(ServerInfo $server, AboutInfo $about, UuidInterface $uuid): void { if (VCenter::exists($uuid->getBytes(), $this->connection)) { $this->logger->info(sprintf('Attached %s to an existing vCenter', $server->get('host'))); @@ -388,7 +446,12 @@ protected function onNewConnectedServer(ServerInfo $server, AboutInfo $about, Uu }); } - protected function onApiConnection(ApiConnection $connection) + /** + * @param ApiConnection $connection + * + * @return void + */ + protected function onApiConnection(ApiConnection $connection): void { $vCenter = VCenter::loadWithAutoIncId( $connection->getServerInfo()->getVCenterId(), @@ -406,7 +469,7 @@ protected function onApiConnection(ApiConnection $connection) $restApi = new RestApi($serverInfo, $vCenter, $this->curl, $logger); $this->launchTasksForConnection($connection, [ new ObjectSync($vCenter, $connection->getApi(), $restApi, $this->dbRunner, $logger), - new PerfDataSync($vCenter, $connection->getApi(), $this->curl, $this->loop, $logger), + new PerfDataSync($vCenter, $connection->getApi(), $this->curl, $this->loop, $logger) ]); } catch (Exception $e) { $this->logger->error($e->getMessage()); @@ -416,8 +479,10 @@ protected function onApiConnection(ApiConnection $connection) /** * @param ApiConnection $connection * @param DaemonTask[] $tasks + * + * @return void */ - protected function launchTasksForConnection(ApiConnection $connection, array $tasks) + protected function launchTasksForConnection(ApiConnection $connection, array $tasks): void { $idx = spl_object_hash($connection); $this->runningTasks[$idx] = $tasks; @@ -427,7 +492,13 @@ protected function launchTasksForConnection(ApiConnection $connection, array $ta } } - protected function prepareApi(LoopInterface $loop, LoggerInterface $logger) + /** + * @param LoopInterface $loop + * @param LoggerInterface $logger + * + * @return void + */ + protected function prepareApi(LoopInterface $loop, LoggerInterface $logger): void { $socketPath = Configuration::getSocketPath(); @@ -463,7 +534,12 @@ function (ServerInfo $server, AboutInfo $info, UuidInterface $uuid) { $this->remoteClient = new RemoteClient($socketPath, $loop); } - protected function stopApiTasksForConnection(ApiConnection $connection) + /** + * @param ApiConnection $connection + * + * @return void + */ + protected function stopApiTasksForConnection(ApiConnection $connection): void { $this->stopApiTasksByConnectionIdx(spl_object_hash($connection)); } @@ -484,7 +560,10 @@ protected function stopApiTasksByConnectionIdx(string $idx): void } } - protected function stopAllApiTasks() + /** + * @return void + */ + protected function stopAllApiTasks(): void { foreach ($this->runningTasks as $tasks) { foreach ($tasks as $task) { @@ -495,7 +574,10 @@ protected function stopAllApiTasks() $this->runningTasks = []; } - protected function onConnected() + /** + * @return void + */ + protected function onConnected(): void { $fail = function (Exception $e) { $this->logger->error($e->getMessage()); @@ -521,16 +603,23 @@ protected function onConnected() ->then($fail); } - protected function hasSchema() + /** + * @return bool + */ + protected function hasSchema(): bool { return (Db::migrationsForDb($this->connection))->hasSchema(); } - protected function sendDbConfigToRunner() + /** + * @return PromiseInterface + */ + protected function sendDbConfigToRunner(): PromiseInterface { $this->logger->notice('[db] sending DB config to child process'); if (! $this->daemonState->getComponentState(self::COMPONENT_DB) === self::STATE_READY) { $this->logger->warning('[db] DB runner is NOT ready, not sending config'); + return resolve(null); } if ($this->dbConfig === null) { @@ -540,14 +629,15 @@ protected function sendDbConfigToRunner() $this->logger->error('[db] clearing DB config failed: ' . $e->getMessage()); $this->setDbState(self::STATE_FAILED); }); - } else { - return $this->dbRunner->request('db.setDbConfig', [ - 'config' => $this->dbConfig - ]); } + + return $this->dbRunner->request('db.setDbConfig', ['config' => $this->dbConfig]); } - protected function reconnectToDb() + /** + * @return void + */ + protected function reconnectToDb(): void { if ($this->connection !== null) { $this->eventuallyDisconnectFromDb(); @@ -566,7 +656,12 @@ protected function reconnectToDb() }); } - protected function connectToDb($config) + /** + * @param $config + * + * @return Db + */ + protected function connectToDb($config): Db { $connection = new Db(new ConfigObject($config)); $connection->getDbAdapter()->getConnection(); @@ -578,7 +673,12 @@ protected function connectToDb($config) return $connection; } - protected function eventuallyDisconnectFromDb($refresh = true) + /** + * @param bool $refresh + * + * @return void + */ + protected function eventuallyDisconnectFromDb(bool $refresh = true): void { if ($this->connection !== null) { try { @@ -603,7 +703,10 @@ protected function eventuallyDisconnectFromDb($refresh = true) } } - protected function runConfigWatch() + /** + * @return void + */ + protected function runConfigWatch(): void { if ($this->configWatch) { return; @@ -616,23 +719,26 @@ protected function runConfigWatch() $config->run($this->loop); } - protected function onDbConfig($config) + /** + * @param ?array $config + * + * @return void + */ + protected function onDbConfig(?array $config): void { if ($config === null) { $this->setDbState('config error'); if ($this->dbConfig === null) { $this->logger->error('[configwatch] Got no valid DB configuration'); + return; - } else { - $this->logger->error('[configwatch] There is no longer a valid DB configuration'); - $this->dbConfig = $config; - $sent = $this->sendDbConfigToRunner(); } + $this->logger->error('[configwatch] There is no longer a valid DB configuration'); } else { $this->logger->notice('[configwatch] DB configuration loaded'); - $this->dbConfig = $config; - $sent = $this->sendDbConfigToRunner(); } + $this->dbConfig = $config; + $sent = $this->sendDbConfigToRunner(); $sent->then(function () { $this->stopComponent(self::COMPONENT_API); $this->setDbState(self::STATE_READY); @@ -642,15 +748,21 @@ protected function onDbConfig($config) }); } - protected function stopConfigWatch() + /** + * @return void + */ + protected function stopConfigWatch(): void { - if ($this->configWatch) { - $this->configWatch->stop(); - $this->configWatch = null; - } + $this->configWatch?->stop(); + $this->configWatch = null; } - protected function refreshMyState($disconnectOnError = true) + /** + * @param bool $disconnectOnError + * + * @return void + */ + protected function refreshMyState(bool $disconnectOnError = true): void { if ($this->connection === null) { return; @@ -659,10 +771,10 @@ protected function refreshMyState($disconnectOnError = true) $db = $this->connection->getDbAdapter(); $updated = $db->update('vspheredb_daemon', [ 'ts_last_refresh' => Util::currentTimestamp(), - 'process_info' => json_encode($this->getProcessInfo()), + 'process_info' => json_encode($this->getProcessInfo()) ], $db->quoteInto('instance_uuid = ?', DbUtil::quoteBinaryCompat($this->processInfo->instance_uuid, $db))); - if (!$updated) { + if (! $updated) { $this->insertMyState($db); } } catch (Exception $e) { @@ -674,33 +786,41 @@ protected function refreshMyState($disconnectOnError = true) } /** - * @param \Zend_Db_Adapter_Abstract $db - * @throws \Zend_Db_Adapter_Exception + * @param Zend_Db_Adapter_Abstract $db + * + * @return void + * + * @throws Zend_Db_Adapter_Exception */ - protected function insertMyState(\Zend_Db_Adapter_Abstract $db) + protected function insertMyState(Zend_Db_Adapter_Abstract $db): void { $db->insert('vspheredb_daemon', [ 'instance_uuid' => $this->processInfo->instance_uuid, 'ts_last_refresh' => Util::currentTimestamp(), - 'process_info' => json_encode($this->getProcessInfo()), + 'process_info' => json_encode($this->getProcessInfo()) ] + (array) $this->processInfo); } - protected function getProcessInfo() + /** + * @return object + */ + protected function getProcessInfo(): object { global $argv; /** @var int $pid */ $pid = $this->processInfo->pid; - $info = (object) [$pid => (object) [ + + return (object) [$pid => (object) [ 'command' => implode(' ', $argv), 'running' => true, 'memory' => Memory::getUsageForPid($pid) ]]; - - return $info; } - protected function refreshConfiguredServers() + /** + * @return void + */ + protected function refreshConfiguredServers(): void { if ($this->connection === null) { return; @@ -717,7 +837,12 @@ protected function refreshConfiguredServers() } } - public function setSystemd(NotifySystemD $systemd) + /** + * @param NotifySystemD $systemd + * + * @return void + */ + public function setSystemd(NotifySystemD $systemd): void { $this->systemd = $systemd; } diff --git a/library/Vspheredb/Data/Anonymizer.php b/library/Vspheredb/Data/Anonymizer.php index 86e0f792..9f46d15d 100644 --- a/library/Vspheredb/Data/Anonymizer.php +++ b/library/Vspheredb/Data/Anonymizer.php @@ -7,9 +7,13 @@ class Anonymizer { - /** @var ?AnonymizerHook */ - protected static $instance = null; + protected static AnonymizerHook|false|null $instance = null; + /** + * @param ?string $string + * + * @return ?string + */ public static function anonymizeString(?string $string): ?string { if ($instance = self::instance()) { @@ -19,6 +23,11 @@ public static function anonymizeString(?string $string): ?string return $string; } + /** + * @param ?string $string + * + * @return ?string + */ public static function shuffleString(?string $string): ?string { if ($instance = self::instance()) { @@ -28,16 +37,20 @@ public static function shuffleString(?string $string): ?string return $string; } + /** + * @return ?AnonymizerHook + */ protected static function instance(): ?AnonymizerHook { if (self::$instance === null) { $instance = Hook::first('vspheredb/Anonymizer'); if ($instance === null) { self::$instance = false; + return null; - } else { - self::$instance = $instance; } + + self::$instance = $instance; } elseif (self::$instance === false) { return null; } diff --git a/library/Vspheredb/Db.php b/library/Vspheredb/Db.php index d102a4d1..e9de608f 100644 --- a/library/Vspheredb/Db.php +++ b/library/Vspheredb/Db.php @@ -10,14 +10,12 @@ class Db extends DbConnection { - public static function newConfiguredInstance() + public static function newConfiguredInstance(): Db { - return static::fromResourceName( - Config::module('vspheredb')->get('db', 'resource') - ); + return static::fromResourceName(Config::module('vspheredb')->get('db', 'resource')); } - public static function migrationsForDb(Db $connection) + public static function migrationsForDb(Db $connection): Migrations { $db = $connection->getDbAdapter(); assert($db instanceof Zend_Db_Adapter_Pdo_Abstract); diff --git a/library/Vspheredb/Db/BulkPathLookup.php b/library/Vspheredb/Db/BulkPathLookup.php index 1debfd75..c72c50c7 100644 --- a/library/Vspheredb/Db/BulkPathLookup.php +++ b/library/Vspheredb/Db/BulkPathLookup.php @@ -8,20 +8,27 @@ class BulkPathLookup { - /** @var Db */ - protected $db; + protected Db $db; - protected $nodes; + protected ?array $nodes = null; - /** @var ?array */ - protected $vCenterFilterUuids; + protected ?array $vCenterFilterUuids; + /** + * @param Db $db + * @param ?array $vCenterUuids + */ public function __construct(Db $db, ?array $vCenterUuids = null) { $this->db = $db; $this->vCenterFilterUuids = $vCenterUuids; } + /** + * @param ?string $objectParent + * + * @return array + */ public function getParents(?string $objectParent): array { if ($this->nodes === null) { @@ -41,6 +48,9 @@ public function getParents(?string $objectParent): array return array_reverse($path, true); } + /** + * @return array + */ protected function fetchAllParents(): array { $db = $this->db->getDbAdapter(); @@ -55,6 +65,7 @@ protected function fetchAllParents(): array foreach ($db->fetchAll($query) as $row) { $result[$row->uuid] = $row; } + return $result; } } diff --git a/library/Vspheredb/Db/CheckRelatedLookup.php b/library/Vspheredb/Db/CheckRelatedLookup.php index 0544b4be..ea7ca17b 100644 --- a/library/Vspheredb/Db/CheckRelatedLookup.php +++ b/library/Vspheredb/Db/CheckRelatedLookup.php @@ -8,18 +8,26 @@ use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; +use InvalidArgumentException; class CheckRelatedLookup { - /** @var Db */ - protected $connection; + protected Db $connection; + /** + * @param Db $connection + */ public function __construct(Db $connection) { $this->connection = $connection; } - public function listNonGreenObjects($type) + /** + * @param string $type + * + * @return array + */ + public function listNonGreenObjects(string $type): array { $db = $this->connection->getDbAdapter(); $select = $db->select() @@ -45,10 +53,12 @@ public function listNonGreenObjects($type) /** * @param string $type * @param array $filter + * * @return BaseDbObject + * * @throws NotFoundError */ - public function findOneBy($type, $filter) + public function findOneBy(string $type, array $filter): BaseDbObject { $result = $this->findBy($type, $filter); @@ -70,9 +80,10 @@ public function findOneBy($type, $filter) /** * @param string $type * @param array $filter + * * @return array */ - private function findBy($type, $filter) + private function findBy(string $type, array $filter): array { $db = $this->connection->getDbAdapter(); $class = static::getClassForType($type); @@ -89,7 +100,7 @@ private function findBy($type, $filter) } if ($value === null) { $select->where($key); - } elseif (strpos($key, '?') === false) { + } elseif (! str_contains($key, '?')) { $select->where("$key = ?", $value); } else { $select->where($key, $value); @@ -102,19 +113,17 @@ private function findBy($type, $filter) /** * @param string $type * - * @return string + * @return class-string + * + * @throws InvalidArgumentException */ private static function getClassForType(string $type): string { - $classes = [ + return match ($type) { 'VirtualMachine' => VirtualMachine::class, 'HostSystem' => HostSystem::class, 'Datastore' => Datastore::class, - ]; - if (! isset($classes[$type])) { - throw new \InvalidArgumentException("'$type' is an unknown type"); - } - - return $classes[$type]; + default => throw new InvalidArgumentException("'$type' is an unknown type") + }; } } diff --git a/library/Vspheredb/Db/DbConnection.php b/library/Vspheredb/Db/DbConnection.php index 3f726cf2..3216ff22 100644 --- a/library/Vspheredb/Db/DbConnection.php +++ b/library/Vspheredb/Db/DbConnection.php @@ -12,17 +12,28 @@ class DbConnection extends IcingaDbConnection { - public function isMysql() + /** + * @return bool + */ + public function isMysql(): bool { return $this->getDbType() === 'mysql'; } - public function isPgsql() + /** + * @return bool + */ + public function isPgsql(): bool { return $this->getDbType() === 'pgsql'; } - public function quoteBinary($binary) + /** + * @param string|array $binary + * + * @return Zend_Db_Expr|array|string + */ + public function quoteBinary(string|array $binary): Zend_Db_Expr|array|string { if ($binary === '') { return ''; @@ -39,7 +50,12 @@ public function quoteBinary($binary) return new Zend_Db_Expr('0x' . bin2hex($binary)); } - public function hasPgExtension($name) + /** + * @param string $name + * + * @return bool + */ + public function hasPgExtension(string $name): bool { $db = $this->getDbAdapter(); $query = $db->select()->from( @@ -50,7 +66,14 @@ public function hasPgExtension($name) return (int) $db->fetchOne($query) === 1; } - public static function pgBinEscape($binary) + /** + * @param $binary + * + * @return Zend_Db_Expr + * + * @throws RuntimeException + */ + public static function pgBinEscape($binary): Zend_Db_Expr { if ($binary instanceof Zend_Db_Expr) { throw new RuntimeException('Trying to escape binary twice'); diff --git a/library/Vspheredb/Db/DbObject.php b/library/Vspheredb/Db/DbObject.php index ee07c33d..c5876f3f 100644 --- a/library/Vspheredb/Db/DbObject.php +++ b/library/Vspheredb/Db/DbObject.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Db; +use Exception; use gipfl\Json\JsonString; use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Db; @@ -10,70 +11,58 @@ use LogicException; use Ramsey\Uuid\Uuid; use RuntimeException; +use stdClass; use Zend_Db_Adapter_Abstract; +use Zend_Db_Adapter_Exception; use Zend_Db_Exception; +use Zend_Db_Expr; +use Zend_Db_Select; /** * Cloned from Director. Should sooner or later be replaced by something modern */ abstract class DbObject { - /** @var DbConnection $connection */ - protected $connection; + protected ?DbConnection $connection = null; - /** @var string Table name. MUST be set when extending this class */ - protected $table; + /** @var ?string Table name. MUST be set when extending this class */ + protected ?string $table = null; - /** @var Zend_Db_Adapter_Abstract */ - protected $db; + protected ?Zend_Db_Adapter_Abstract $db = null; /** * Default columns. MUST be set when extending this class. Each table * column MUST be defined with a default value. Default value may be null. * - * @var array + * @var ?array */ - protected $defaultProperties; + protected ?array $defaultProperties = null; - /** - * Properties as loaded from db - */ - protected $loadedProperties; + /** @var ?array Properties as loaded from db */ + protected ?array $loadedProperties = null; - /** - * Whether at least one property has been modified - */ - protected $hasBeenModified = false; + /** @var bool Whether at least one property has been modified */ + protected bool $hasBeenModified = false; - /** - * Whether this object has been loaded from db - */ - protected $loadedFromDb = false; + /** @var bool Whether this object has been loaded from db */ + protected bool $loadedFromDb = false; - /** - * Object properties - */ - protected $properties = []; + /** @var array Object properties */ + protected array $properties = []; - /** - * Property names that have been modified since object creation - */ - protected $modifiedProperties = []; + /** @var array Property names that have been modified since object creation */ + protected array $modifiedProperties = []; - /** - * Unique key name, could be primary - */ - protected $keyName; + /** @var string|string[]|null Unique key name, could be primary */ + protected string|array|null $keyName = null; - /** - * Set this to an eventual autoincrementing column. May equal $keyName - */ - protected $autoincKeyName; + /** @var ?string Set this to an eventual autoincrementing column. May equal $keyName */ + protected ?string $autoincKeyName = null; /** @var bool forbid updates to autoinc values */ - protected $protectAutoinc = true; + protected bool $protectAutoinc = true; - protected $binaryProperties = []; + protected array $binaryProperties = []; /** * Constructor is not accessible and should not be overridden @@ -92,7 +81,10 @@ protected function __construct() $this->beforeInit(); } - public function getTableName() + /** + * @return ?string + */ + public function getTableName(): ?string { return $this->table; } @@ -108,9 +100,9 @@ public function getTableName() * the object. Please note that the method is public and allows to check * object consistence at any time. * - * @return boolean Whether this object is valid + * @return boolean Whether this object is valid */ - public function validate() + public function validate(): bool { return true; } @@ -121,7 +113,7 @@ public function validate() * * @return void */ - protected function beforeInit() + protected function beforeInit(): void { } @@ -131,7 +123,7 @@ protected function beforeInit() * * @return void */ - protected function onLoadFromDb() + protected function onLoadFromDb(): void { } @@ -142,67 +134,66 @@ protected function onLoadFromDb() * * @return void */ - protected function beforeStore() + protected function beforeStore(): void { } /** - * Wird ausgeführt, nachdem ein Objekt erfolgreich gespeichert worden ist + * Will be executed after an object has been stored successfully * * @return void */ - protected function onStore() + protected function onStore(): void { } /** - * Wird ausgeführt, nachdem ein Objekt erfolgreich der Datenbank hinzu- - * gefügt worden ist + * Will be executed after an object has successfully been inserted into the + * database * * @return void */ - protected function onInsert() + protected function onInsert(): void { } /** - * Wird ausgeführt, nachdem bestehendes Objekt erfolgreich der Datenbank - * geändert worden ist + * Will be executed after an existing object has been successfully updated * * @return void */ - protected function onUpdate() + protected function onUpdate(): void { } /** - * Wird ausgeführt, bevor ein Objekt gelöscht wird. Die Operation wird - * aber auf jeden Fall durchgeführt, außer man wirft eine Exception + * Will be executed before an object will be deleted. The operation will + * definitely be executed, except an exception is thrown. * * @return void */ - protected function beforeDelete() + protected function beforeDelete(): void { } /** - * Wird ausgeführt, nachdem bestehendes Objekt erfolgreich aud der - * Datenbank gelöscht worden ist + * Will be executed after an existing object has been successfully deleted + * from the database * * @return void */ - protected function onDelete() + protected function onDelete(): void { } /** * Set database connection * - * @param DbConnection $connection Database connection + * @param ?DbConnection $connection Database connection * - * @return self + * @return $this */ - public function setConnection(DbConnection $connection) + public function setConnection(?DbConnection $connection): static { $this->connection = $connection; $this->db = $connection->getDbAdapter(); @@ -217,10 +208,10 @@ public function setConnection(DbConnection $connection) * * @return mixed */ - public function get($property) + public function get(string $property): mixed { $func = 'get' . ucfirst($property); - if (substr($func, -2) === '[]') { + if (str_ends_with($func, '[]')) { $func = substr($func, 0, -2); } // TODO: id check avoids collision with getId. Rethink this. @@ -229,6 +220,7 @@ public function get($property) } $this->assertPropertyExists($property); + return $this->properties[$property]; } @@ -244,7 +236,14 @@ public function getProperty(string $key): mixed return $this->properties[$key]; } - protected function assertPropertyExists($key) + /** + * @param string $key + * + * @return $this + * + * @throws InvalidArgumentException + */ + protected function assertPropertyExists(string $key): static { if (! array_key_exists($key, $this->properties)) { throw new InvalidArgumentException(sprintf( @@ -256,7 +255,12 @@ protected function assertPropertyExists($key) return $this; } - public function hasProperty($key) + /** + * @param string $key + * + * @return bool + */ + public function hasProperty(string $key): bool { if (array_key_exists($key, $this->properties)) { return true; @@ -265,12 +269,13 @@ public function hasProperty($key) return false; } $func = 'get' . ucfirst($key); - if (substr($func, -2) === '[]') { + if (str_ends_with($func, '[]')) { $func = substr($func, 0, -2); } if (method_exists($this, $func)) { return true; } + return false; } @@ -278,13 +283,12 @@ public function hasProperty($key) * Generic setter * * @param string $key - * @param mixed $value + * @param mixed $value * - * @return self + * @return $this|null */ - public function set($key, $value) + public function set(string $key, mixed $value): ?static { - $key = (string) $key; if ($value === '') { $value = null; } @@ -303,7 +307,7 @@ public function set($key, $value) } $func = 'set' . ucfirst($key); - if (substr($func, -2) === '[]') { + if (str_ends_with($func, '[]')) { $func = substr($func, 0, -2); } @@ -318,10 +322,7 @@ public function set($key, $value) )); } - if ( - (is_numeric($value) || is_string($value)) - && (string) $value === (string) $this->get($key) - ) { + if ((is_numeric($value) || is_string($value)) && (string) $value === (string) $this->get($key)) { return $this; } @@ -334,11 +335,11 @@ public function set($key, $value) /** * @param string $key - * @param $value + * @param mixed $value * * @return $this */ - protected function reallySet(string $key, $value): static + protected function reallySet(string $key, mixed $value): static { if ($value === $this->properties[$key]) { return $this; @@ -354,11 +355,11 @@ protected function reallySet(string $key, $value): static /** * Magic getter * - * @param mixed $key + * @param string $key * * @return mixed */ - public function __get($key) + public function __get(string $key): mixed { return $this->get($key); } @@ -366,12 +367,12 @@ public function __get($key) /** * Magic setter * - * @param string $key Key - * @param mixed $val Value + * @param string $key Key + * @param mixed $val Value * * @return void */ - public function __set($key, $val) + public function __set(string $key, mixed $val): void { $this->set($key, $val); } @@ -379,10 +380,11 @@ public function __set($key, $val) /** * Magic isset check * - * @param string $key - * @return boolean + * @param string $key + * + * @return bool */ - public function __isset($key) + public function __isset(string $key): bool { return array_key_exists($key, $this->properties); } @@ -405,17 +407,12 @@ public function __unset(string $key): void /** * Runs set() for every key/value pair of the given Array * - * @param array $props Array of properties - * @return self + * @param array $props Array of properties + * + * @return $this */ - public function setProperties($props) + public function setProperties(array $props): static { - if (! is_array($props)) { - throw new InvalidArgumentException(sprintf( - 'Array required, got %s', - gettype($props) - )); - } foreach ($props as $key => $value) { $this->set($key, $value); } @@ -427,7 +424,7 @@ public function setProperties($props) * * @return array */ - public function getProperties() + public function getProperties(): array { //return $this->properties; $res = []; @@ -438,12 +435,18 @@ public function getProperties() return $res; } - protected function getPropertiesForDb() + /** + * @return ?array + */ + protected function getPropertiesForDb(): ?array { return $this->properties; } - public function listProperties() + /** + * @return array + */ + public function listProperties(): array { return array_keys($this->properties); } @@ -453,20 +456,17 @@ public function listProperties() * * @return array */ - public function getModifiedProperties() + public function getModifiedProperties(): array { $props = []; foreach (array_keys($this->modifiedProperties) as $key) { - if ($key === $this->autoincKeyName) { - if ($this->protectAutoinc) { - continue; - } elseif ($this->properties[$key] === null) { - continue; - } + if ($key === $this->autoincKeyName && ($this->protectAutoinc || $this->properties[$key] === null)) { + continue; } $props[$key] = $this->properties[$key]; } + return $props; } @@ -475,7 +475,7 @@ public function getModifiedProperties() * * @return array */ - public function listModifiedProperties() + public function listModifiedProperties(): array { return array_keys($this->modifiedProperties); } @@ -485,7 +485,7 @@ public function listModifiedProperties() * * @return bool */ - public function hasBeenModified() + public function hasBeenModified(): bool { return $this->hasBeenModified; } @@ -493,10 +493,11 @@ public function hasBeenModified() /** * Whether the given property has been modified * - * @param string $key Property name - * @return boolean + * @param string $key Property name + * + * @return bool */ - protected function hasModifiedProperty($key) + protected function hasModifiedProperty(string $key): bool { return array_key_exists($key, $this->modifiedProperties); } @@ -521,7 +522,10 @@ public function getAutoincKeyName(): ?string return $this->autoincKeyName; } - public function getKeyParams() + /** + * @return array + */ + public function getKeyParams(): array { $params = []; $key = $this->getKeyName(); @@ -542,11 +546,11 @@ public function getKeyParams() * * // TODO: may conflict with ->id * - * @throws InvalidArgumentException When key can not be calculated + * @return string|array|null * - * @return string|array + * @throws InvalidArgumentException When key can not be calculated */ - public function getId() + public function getId(): array|string|null { $keyName = $this->getKeyName(); if (is_array($keyName)) { @@ -563,29 +567,33 @@ public function getId() } return $id; - } else { - if (isset($this->properties[$keyName])) { - return $this->properties[$keyName]; - } } + if (isset($this->properties[$keyName])) { + return $this->properties[$keyName]; + } + return null; } /** * Get the autoinc value if set * - * @return int + * @return ?int */ - public function getAutoincId() + public function getAutoincId(): ?int { $autoincKeyName = $this->getAutoincKeyName(); if ($autoincKeyName !== null && isset($this->properties[$autoincKeyName])) { return (int) $this->properties[$autoincKeyName]; } + return null; } - protected function forgetAutoincId() + /** + * @return $this + */ + protected function forgetAutoincId(): static { $autoincKeyName = $this->getAutoincKeyName(); if ($autoincKeyName !== null && isset($this->properties[$autoincKeyName])) { @@ -596,51 +604,46 @@ protected function forgetAutoincId() } /** - * Liefert das benutzte Datenbank-Handle + * Returns the used database handle * - * @return Zend_Db_Adapter_Abstract + * @return ?Zend_Db_Adapter_Abstract */ - public function getDb() + public function getDb(): ?Zend_Db_Adapter_Abstract { return $this->db; } - public function hasConnection() + public function hasConnection(): bool { return $this->connection !== null; } - public function getConnection() + /** + * @return ?DbConnection + */ + public function getConnection(): ?DbConnection { return $this->connection; } /** - * Lädt einen Datensatz aus der Datenbank und setzt die entsprechenden - * Eigenschaften dieses Objekts + * Loads a record from the database and sets the corresponding properties + * on the object + * + * @return $this * * @throws NotFoundError - * @return self */ - protected function loadFromDb() + protected function loadFromDb(): static { $select = $this->db->select()->from($this->table)->where($this->createWhere()); $properties = $this->db->fetchRow($select); if (empty($properties)) { if (is_array($this->getKeyName())) { - throw new NotFoundError( - 'Failed to load %s for %s', - $this->table, - $this->createWhere() - ); - } else { - throw new NotFoundError( - 'Failed to load %s "%s"', - $this->table, - $this->getLogId() - ); + throw new NotFoundError('Failed to load %s for %s', $this->table, $this->createWhere()); } + throw new NotFoundError('Failed to load %s "%s"', $this->table, $this->getLogId()); } return $this->setDbProperties($properties); @@ -649,16 +652,22 @@ protected function loadFromDb() /** * @param object $row * @param Db $db - * @return self + * + * @return static */ - public static function fromDbRow($row, Db $db) + public static function fromDbRow(object $row, Db $db): static { return (new static()) ->setConnection($db) ->setDbProperties($row); } - public function setDbProperties($properties) + /** + * @param array|stdClass $properties + * + * @return $this + */ + public function setDbProperties(array|stdClass $properties): static { foreach ($properties as $key => $val) { if (! array_key_exists($key, $this->properties)) { @@ -682,10 +691,14 @@ public function setDbProperties($properties) $this->hasBeenModified = false; $this->modifiedProperties = []; $this->onLoadFromDb(); + return $this; } - public function getOriginalProperties() + /** + * @return ?array + */ + public function getOriginalProperties(): ?array { return $this->loadedProperties; } @@ -693,7 +706,7 @@ public function getOriginalProperties() /** * @param string $key * - * @return mixed|null + * @return ?mixed */ public function getOriginalProperty(string $key): mixed { @@ -720,18 +733,22 @@ public function resetProperty(string $key): static return $this; } - public function hasBeenLoadedFromDb() + /** + * @return bool + */ + public function hasBeenLoadedFromDb(): bool { return $this->loadedFromDb; } /** - * Ändert den entsprechenden Datensatz in der Datenbank + * Updates the corresponding record in the database * - * @return int Anzahl der geänderten Zeilen - * @throws \Zend_Db_Adapter_Exception + * @return int|true Number of updated rows + * + * @throws Zend_Db_Adapter_Exception */ - protected function updateDb() + protected function updateDb(): int|true { $properties = $this->getModifiedProperties(); if (empty($properties)) { @@ -748,12 +765,13 @@ protected function updateDb() } /** - * Fügt der Datenbank-Tabelle einen entsprechenden Datensatz hinzu + * Inserts a record into the database table + * + * @return int Number of affected rows * - * @return int Anzahl der betroffenen Zeilen - * @throws \Zend_Db_Adapter_Exception + * @throws Zend_Db_Adapter_Exception */ - protected function insertIntoDb() + protected function insertIntoDb(): int { $properties = $this->getPropertiesForDb(); $autoincKeyName = $this->getAutoincKeyName(); @@ -774,7 +792,12 @@ protected function insertIntoDb() return $this->db->insert($this->table, $properties); } - protected function isBinaryColumn($column) + /** + * @param string $column + * + * @return bool + */ + protected function isBinaryColumn(string $column): bool { return in_array($column, $this->binaryProperties); } @@ -782,11 +805,15 @@ protected function isBinaryColumn($column) /** * Store object to database * - * @param DbConnection $db - * @return bool Whether storing succeeded + * @param ?DbConnection $db + * + * @return true Whether storing succeeded + * + * @throws InvalidArgumentException + * @throws RuntimeException * @throws DuplicateKeyException */ - public function store(?DbConnection $db = null) + public function store(?DbConnection $db = null): true { if ($db !== null) { $this->setConnection($db); @@ -810,15 +837,10 @@ public function store(?DbConnection $db = null) try { if ($this->hasBeenLoadedFromDb()) { - if ($this->updateDb() !== false) { - $result = true; + if ($this->updateDb()) { $this->onUpdate(); } else { - throw new RuntimeException(sprintf( - 'FAILED storing %s "%s"', - $table, - $this->getLogId() - )); + throw new RuntimeException(sprintf('FAILED storing %s "%s"', $table, $this->getLogId())); } } else { $autoincKeyName = $this->getAutoincKeyName(); @@ -828,30 +850,19 @@ public function store(?DbConnection $db = null) if ($autoId = $this->getAutoincId()) { $logId .= sprintf(', %s=%s', $autoincKeyName, $autoId); } - throw new DuplicateKeyException( - 'Trying to recreate %s (%s)', - $table, - $logId - ); + throw new DuplicateKeyException('Trying to recreate %s (%s)', $table, $logId); } if ($this->insertIntoDb()) { if ($autoincKeyName && $this->getProperty($autoincKeyName) === null) { - if ($this->connection->isPgsql()) { - $this->properties[$autoincKeyName] = $this->db->lastInsertId($table, $autoincKeyName); - } else { - $this->properties[$autoincKeyName] = $this->db->lastInsertId(); - } + $this->properties[$autoincKeyName] = $this->connection->isPgsql() + ? $this->db->lastInsertId($table, $autoincKeyName) + : $this->db->lastInsertId(); } // $this->log(sprintf('New %s "%s" has been stored', $table, $id)); $this->onInsert(); - $result = true; } else { - throw new RuntimeException(sprintf( - 'FAILED to store new %s "%s"', - $table, - $this->getLogId() - )); + throw new RuntimeException(sprintf('FAILED to store new %s "%s"', $table, $this->getLogId())); } } } catch (Zend_Db_Exception $e) { @@ -870,15 +881,15 @@ public function store(?DbConnection $db = null) $this->onStore(); $this->loadedFromDb = true; - return $result; + return true; } /** * Delete item from DB * - * @return int Affected rows + * @return int Affected rows */ - protected function deleteFromDb() + protected function deleteFromDb(): int { return $this->db->delete( $this->table, @@ -890,9 +901,10 @@ protected function deleteFromDb() * @param string[]|string $key * * @return self + * * @throws InvalidArgumentException */ - protected function setKey(array|string $key) + protected function setKey(array|string $key): static { $keyname = $this->getKeyName(); if (is_array($keyname)) { @@ -913,10 +925,14 @@ protected function setKey(array|string $key) } else { $this->set($keyname, $key); } + return $this; } - protected function existsInDb() + /** + * @return bool + */ + protected function existsInDb(): bool { $result = $this->db->fetchRow( $this->db->select()->from($this->table)->where($this->createWhere()) @@ -924,7 +940,10 @@ protected function existsInDb() return $result !== false; } - public function createWhere() + /** + * @return string + */ + public function createWhere(): string { if ($id = $this->getAutoincId()) { if ($originalId = $this->getOriginalProperty($this->autoincKeyName)) { @@ -946,31 +965,32 @@ public function createWhere() /** @var string $k */ foreach ($key as $k) { if ($this->hasBeenLoadedFromDb()) { - if ($this->loadedProperties[$k] === null) { - $where[] = sprintf('%s IS NULL', $k); - } else { - $where[] = $this->createQuotedWhere($k, $this->loadedProperties[$k]); - } + $where[] = $this->loadedProperties[$k] === null + ? sprintf('%s IS NULL', $k) + : $this->createQuotedWhere($k, $this->loadedProperties[$k]); } else { - if ($this->properties[$k] === null) { - $where[] = sprintf('%s IS NULL', $k); - } else { - $where[] = $this->createQuotedWhere($k, $this->properties[$k]); - } + $where[] = $this->properties[$k] === null + ? sprintf('%s IS NULL', $k) + : $this->createQuotedWhere($k, $this->properties[$k]); } } return implode(' AND ', $where); - } else { - if ($this->hasBeenLoadedFromDb()) { - return $this->createQuotedWhere($key, $this->loadedProperties[$key]); - } else { - return $this->createQuotedWhere($key, $this->properties[$key]); - } } + + return $this->createQuotedWhere( + $key, + $this->hasBeenLoadedFromDb() ? $this->loadedProperties[$key] : $this->properties[$key] + ); } - protected function createQuotedWhere($column, $value) + /** + * @param string $column + * @param mixed $value + * + * @return string + */ + protected function createQuotedWhere(string $column, mixed $value): string { return $this->db->quoteInto( sprintf('%s = ?', $column), @@ -978,16 +998,25 @@ protected function createQuotedWhere($column, $value) ); } - protected function eventuallyQuoteBinary($value, $column) + /** + * @param mixed $value + * @param string $column + * + * @return array|mixed|string|Zend_Db_Expr + */ + protected function eventuallyQuoteBinary(mixed $value, string $column): mixed { if ($this->isBinaryColumn($column)) { return $this->connection->quoteBinary($value); - } else { - return $value; } + + return $value; } - protected function getLogId() + /** + * @return mixed|string + */ + protected function getLogId(): mixed { if (is_array($this->keyName)) { $id = []; @@ -999,7 +1028,7 @@ protected function getLogId() } try { return JsonString::encode($id); - } catch (\Exception $e) { + } catch (Exception $e) { return 'Key encoding failed: ' . $e->getMessage(); } } @@ -1009,12 +1038,14 @@ protected function getLogId() /** * @param string $name + * + * @return mixed|string */ - protected function getReadableProperty(string $name) + protected function getReadableProperty(string $name): mixed { if (isset($this->properties[$name])) { $value = $this->properties[$name]; - if (preg_match('/uuid$/', $name) && strlen($value) === 16) { + if (str_ends_with($name, 'uuid') && strlen($value) === 16) { return Uuid::fromBytes($value)->toString(); } @@ -1024,7 +1055,10 @@ protected function getReadableProperty(string $name) return $this->defaultProperties[$name]; } - public function delete() + /** + * @return true + */ + public function delete(): true { $table = $this->table; @@ -1054,10 +1088,14 @@ public function delete() // $this->log(sprintf('%s "%s" has been DELETED', $table, this->getLogId())); $this->onDelete(); $this->loadedFromDb = false; + return true; } - public function __clone() + /** + * @return void + */ + public function __clone(): void { $this->onClone(); $this->forgetAutoincId(); @@ -1065,17 +1103,20 @@ public function __clone() $this->hasBeenModified = true; } - protected function onClone() + /** + * @return void + */ + protected function onClone(): void { } /** * @param array $properties - * @param DbConnection|null $connection + * @param ?DbConnection $connection * * @return static */ - public static function create($properties = [], ?DbConnection $connection = null) + public static function create(array $properties = [], ?DbConnection $connection = null): static { $obj = new static(); if ($connection !== null) { @@ -1086,12 +1127,14 @@ public static function create($properties = [], ?DbConnection $connection = null } /** - * @param $id - * @param DbConnection $connection + * @param int|string $id + * @param ?DbConnection $connection + * * @return static + * * @throws NotFoundError */ - public static function loadWithAutoIncId($id, DbConnection $connection) + public static function loadWithAutoIncId(int|string $id, ?DbConnection $connection): static { /* Need to cast to int, otherwise the id will be matched against * object_name, which may wreak havoc if an object has a @@ -1110,12 +1153,14 @@ public static function loadWithAutoIncId($id, DbConnection $connection) } /** - * @param $id + * @param string $id * @param DbConnection $connection + * * @return static + * * @throws NotFoundError */ - public static function load($id, DbConnection $connection) + public static function load(string $id, DbConnection $connection): static { $obj = new static(); $obj->setConnection($connection)->setKey($id)->loadFromDb(); @@ -1125,13 +1170,16 @@ public static function load($id, DbConnection $connection) /** * @param DbConnection $connection - * @param \Zend_Db_Select $query - * @param string|null $keyColumn + * @param ?Zend_Db_Select $query + * @param ?string $keyColumn * * @return static[] */ - public static function loadAll(DbConnection $connection, $query = null, $keyColumn = null) - { + public static function loadAll( + DbConnection $connection, + ?Zend_Db_Select $query = null, + ?string $keyColumn = null + ): array { $objects = []; $db = $connection->getDbAdapter(); @@ -1144,7 +1192,6 @@ public static function loadAll(DbConnection $connection, $query = null, $keyColu $rows = $db->fetchAll($select); foreach ($rows as $row) { - /** @var DbObject $obj */ $obj = new static(); $obj->setConnection($connection)->setDbProperties($row); if ($keyColumn === null) { @@ -1168,12 +1215,14 @@ public static function loadAll(DbConnection $connection, $query = null, $keyColu /** * @param $id * @param DbConnection $connection + * * @return bool */ - public static function exists($id, DbConnection $connection) + public static function exists($id, DbConnection $connection): bool { $obj = new static(); $obj->setConnection($connection)->setKey($id); + return $obj->existsInDb(); } diff --git a/library/Vspheredb/Db/DbUtil.php b/library/Vspheredb/Db/DbUtil.php index adff3318..016b8179 100644 --- a/library/Vspheredb/Db/DbUtil.php +++ b/library/Vspheredb/Db/DbUtil.php @@ -16,7 +16,12 @@ class DbUtil { - public static function binaryResult($value) + /** + * @param $value + * + * @return false|mixed|string + */ + public static function binaryResult($value): mixed { if (is_resource($value)) { return stream_get_contents($value); @@ -26,12 +31,15 @@ public static function binaryResult($value) } /** - * @param string|array $binary + * @param array|string|null $binary * @param Zend_Db_Adapter_Abstract $db - * @return Zend_Db_Expr|Zend_Db_Expr[] + * + * @return Zend_Db_Expr|Zend_Db_Expr[]|null */ - public static function quoteBinaryLegacy($binary, $db) - { + public static function quoteBinaryLegacy( + array|string|null $binary, + Zend_Db_Adapter_Abstract $db + ): Zend_Db_Expr|array|null { if (is_array($binary)) { return static::quoteArray($binary, 'quoteBinaryLegacy', $db); } @@ -48,11 +56,12 @@ public static function quoteBinaryLegacy($binary, $db) } /** - * @param string|array $binary + * @param array|string|null $binary * @param Adapter $db - * @return Expr|Expr[] + * + * @return Expr|Expr[]|null */ - public static function quoteBinary($binary, $db) + public static function quoteBinary(array|string|null $binary, Adapter $db): Expr|array|null { if (is_array($binary)) { return static::quoteArray($binary, 'quoteBinary', $db); @@ -70,12 +79,15 @@ public static function quoteBinary($binary, $db) } /** - * @param string|array $binary - * @param Adapter|Zend_Db_Adapter_Abstract $db - * @return Expr|Zend_Db_Expr|Expr[]|Zend_Db_Expr[] + * @param array|string|null $binary + * @param Zend_Db_Adapter_Abstract|Adapter $db + * + * @return Expr|Zend_Db_Expr|Expr[]|Zend_Db_Expr[]|null */ - public static function quoteBinaryCompat($binary, $db) - { + public static function quoteBinaryCompat( + array|string|null $binary, + Zend_Db_Adapter_Abstract|Adapter $db + ): Zend_Db_Expr|Expr|array|null { if ($db instanceof Adapter) { return static::quoteBinary($binary, $db); } @@ -83,7 +95,14 @@ public static function quoteBinaryCompat($binary, $db) return static::quoteBinaryLegacy($binary, $db); } - protected static function quoteArray($array, $method, $db) + /** + * @param array $array + * @param string $method + * @param Adapter|Zend_Db_Adapter_Abstract $db + * + * @return array + */ + protected static function quoteArray(array $array, string $method, Adapter|Zend_Db_Adapter_Abstract $db): array { $result = []; foreach ($array as $bin) { diff --git a/library/Vspheredb/Db/QueryHelper.php b/library/Vspheredb/Db/QueryHelper.php index 29d55771..5424094e 100644 --- a/library/Vspheredb/Db/QueryHelper.php +++ b/library/Vspheredb/Db/QueryHelper.php @@ -3,11 +3,24 @@ namespace Icinga\Module\Vspheredb\Db; use Zend_Db_Adapter_Abstract as ZfDb; +use Zend_Db_Select; class QueryHelper { - public static function applyOptionalVCenterFilter(ZfDb $db, $query, string $column, ?array $vCenterFilterUuids) - { + /** + * @param ZfDb $db + * @param Zend_Db_Select $query + * @param string $column + * @param ?array $vCenterFilterUuids + * + * @return void + */ + public static function applyOptionalVCenterFilter( + ZfDb $db, + Zend_Db_Select $query, + string $column, + ?array $vCenterFilterUuids + ): void { if ($vCenterFilterUuids === null) { return; } diff --git a/library/Vspheredb/Db/TagLookup.php b/library/Vspheredb/Db/TagLookup.php index 3dc30cb5..05f3fb12 100644 --- a/library/Vspheredb/Db/TagLookup.php +++ b/library/Vspheredb/Db/TagLookup.php @@ -10,18 +10,19 @@ class TagLookup { - /** @var Db */ - protected $db; + protected Db $db; - /** @var array */ - protected $assignments; + protected array $assignments; /** @var TaggingTag[] */ - protected $tags; + protected array $tags; /** @var TaggingCategory[] */ - protected $categories; + protected array $categories; + /** + * @param Db $db + */ public function __construct(Db $db) { $this->db = $db; @@ -30,6 +31,11 @@ public function __construct(Db $db) $this->categories = TaggingCategory::loadAll($this->db, null, 'uuid'); } + /** + * @param string $objectUuid + * + * @return stdClass + */ public function getTags(string $objectUuid): stdClass { if (!isset($this->assignments[$objectUuid])) { @@ -71,6 +77,9 @@ public function getTags(string $objectUuid): stdClass return (object) $result; } + /** + * @return array + */ protected function fetchAllAssignments(): array { $db = $this->db->getDbAdapter(); diff --git a/library/Vspheredb/Db/VCenterCleanup.php b/library/Vspheredb/Db/VCenterCleanup.php index 8137c181..9b2985a6 100644 --- a/library/Vspheredb/Db/VCenterCleanup.php +++ b/library/Vspheredb/Db/VCenterCleanup.php @@ -3,23 +3,35 @@ namespace Icinga\Module\Vspheredb\Db; use Exception; -use gipfl\ZfDb\Adapter\Adapter; use Icinga\Module\Vspheredb\Db; use InvalidArgumentException; use React\EventLoop\Loop; use React\Promise\Deferred; use React\Promise\PromiseInterface; +use RuntimeException; +use Throwable; +use Zend_Db_Adapter_Abstract; class VCenterCleanup { protected Db $connection; + protected int $vCenterId; + protected array $scheduledQueries = []; + protected string $vCenterUuid; + protected ?Deferred $deferred = null; - /** @var \Zend_Db_Adapter_Abstract|Adapter */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; + + /** + * @param Db $connection + * @param int $vCenterId + * + * @throws InvalidArgumentException + */ public function __construct(Db $connection, int $vCenterId) { $this->connection = $connection; @@ -33,6 +45,11 @@ public function __construct(Db $connection, int $vCenterId) $this->vCenterUuid = $uuid; } + /** + * @return PromiseInterface + * + * @throws RuntimeException + */ public function run(): PromiseInterface { if ($this->deferred !== null) { @@ -45,25 +62,27 @@ public function run(): PromiseInterface return $this->deferred->promise(); } + /** + * @return void + */ protected function tick(): void { $query = array_shift($this->scheduledQueries); if ($query === null) { - if ($this->deferred) { - // Should never be null, this is just a safety measure - $this->deferred->resolve(true); - } + // Should never be null, this is just a safety measure + $this->deferred?->resolve(true); + return; } try { $this->db->query($query[0], $query[1]); Loop::futureTick(fn () => $this->tick()); - } catch (\Throwable $e) { + } catch (Throwable $e) { $deferred = $this->deferred; $this->scheduledQueries = []; $this->deferred = null; - $deferred->reject(new \Exception(sprintf( + $deferred->reject(new Exception(sprintf( "Query %s failed: %s", $query[0], $e->getMessage() @@ -71,6 +90,9 @@ protected function tick(): void } } + /** + * @return void + */ protected function scheduleQueries(): void { $uuid = $this->vCenterUuid; @@ -158,7 +180,7 @@ protected function scheduleQueries(): void ['DELETE FROM object WHERE vcenter_uuid = ? ORDER BY level DESC;', [$uuid]], ['OPTIMIZE TABLE object', []], ['DELETE FROM vcenter WHERE id = ?;', [$this->vCenterId]], - ['OPTIMIZE TABLE vcenter', []], + ['OPTIMIZE TABLE vcenter', []] ]; } } diff --git a/library/Vspheredb/DbObject/BaseDbObject.php b/library/Vspheredb/DbObject/BaseDbObject.php index 56642b3c..4af2dc31 100644 --- a/library/Vspheredb/DbObject/BaseDbObject.php +++ b/library/Vspheredb/DbObject/BaseDbObject.php @@ -3,82 +3,95 @@ namespace Icinga\Module\Vspheredb\DbObject; use gipfl\Json\JsonSerialization; -use Icinga\Module\Vspheredb\Db\DbObject as VspheredbDbObject; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Db; +use Icinga\Module\Vspheredb\Db\DbObject as VspheredbDbObject; use Icinga\Module\Vspheredb\MappedClass\ElementDescription; use Icinga\Module\Vspheredb\Util; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; +use InvalidArgumentException; use Ramsey\Uuid\Uuid; +use ReturnTypeWillChange; abstract class BaseDbObject extends VspheredbDbObject implements JsonSerialization { - /** @var Db $connection Exists in parent, but IDEs need a better hint */ - protected $connection; + protected string|array|null $keyName = 'id'; - protected $keyName = 'id'; + private ?ManagedObject $object = null; - /** @var ManagedObject */ - private $object; + protected array $propertyMap = []; - protected $propertyMap = []; + protected array $objectReferences = []; - protected $objectReferences = []; + protected array $booleanProperties = []; - protected $booleanProperties = []; - - protected $dateTimeProperties = []; + protected array $dateTimeProperties = []; /** * @param string $uuid * @param Db $connection + * * @return static - * @throws \Icinga\Exception\NotFoundError + * + * @throws NotFoundError */ - public static function loadWithUuid(string $uuid, Db $connection) + public static function loadWithUuid(string $uuid, Db $connection): static { - if (strlen($uuid) === 16) { - $uuid = Uuid::fromBytes($uuid); - } else { - $uuid = Uuid::fromString($uuid); - } + $uuid = strlen($uuid) === 16 ? Uuid::fromBytes($uuid) : Uuid::fromString($uuid); return static::load($uuid->getBytes(), $connection); } - public function isObjectReference($property) + /** + * @param string $property + * + * @return bool + */ + public function isObjectReference(string $property): bool { return $property === 'parent' || in_array($property, $this->objectReferences); } - public function isBooleanProperty($property) + /** + * @param string $property + * + * @return bool + */ + public function isBooleanProperty(string $property): bool { return in_array($property, $this->booleanProperties); } - protected function isBinaryColumn($column) + protected function isBinaryColumn(string $column): bool { if ($this->isObjectReference($column)) { return true; } - if ($column === 'uuid' || substr($column, -5) === '_uuid') { + if ($column === 'uuid' || str_ends_with($column, '_uuid')) { return true; } return parent::isBinaryColumn($column); } - public function isDateTimeProperty($property) + /** + * @param string $property + * + * @return bool + */ + public function isDateTimeProperty(string $property): bool { return in_array($property, $this->dateTimeProperties); } /** - * @param $properties + * @param object $properties * @param VCenter $vCenter + * * @return $this */ - public function setMapped($properties, VCenter $vCenter) + public function setMapped(object $properties, VCenter $vCenter): static { if ($this->hasProperty('vcenter_uuid')) { $this->set('vcenter_uuid', $vCenter->getUuid()); @@ -96,7 +109,7 @@ public function setMapped($properties, VCenter $vCenter) // Like HostNumericSensorInfo.healthState // Hint: lcfirst -> issue #179, vSphere 7 ships 'Green' instead of 'green', // at least on that specific system - $value = \lcfirst($value->key); + $value = lcfirst($value->key); } if ($property === 'customValues') { if (empty((array) $value)) { @@ -113,8 +126,11 @@ public function setMapped($properties, VCenter $vCenter) return $this; } - #[\ReturnTypeWillChange] - public function jsonSerialize() + #[ReturnTypeWillChange] + /** + * @return object + */ + public function jsonSerialize(): object { $serialized = []; foreach ($this->getProperties() as $key => $value) { @@ -122,7 +138,7 @@ public function jsonSerialize() $value = DbProperty::dbToBoolean($value); } elseif ($this->isObjectReference($key)) { $value = Uuid::fromBytes($value)->toString(); - } elseif ($key === 'uuid' || substr($key, -5) === '_uuid') { // Hint: SHOULD be keys or references + } elseif ($key === 'uuid' || str_ends_with($key, '_uuid')) { // Hint: SHOULD be keys or references if (strlen($value) === 16) { $value = Uuid::fromBytes($value)->toString(); } elseif ($value !== null) { @@ -139,44 +155,60 @@ public function jsonSerialize() return (object) $serialized; } - public static function fromSerialization($any) + /** + * @param mixed $any + * + * @return static + */ + public static function fromSerialization(mixed $any): static { return static::create((array) $any); } - protected function createUuidForMoref($value, VCenter $vCenter) + /** + * @param mixed $value + * @param VCenter $vCenter + * + * @return ?string + */ + protected function createUuidForMoref(mixed $value, VCenter $vCenter): ?string { if (empty($value)) { return null; - } elseif ($value instanceof ManagedObjectReference) { + } + + if ($value instanceof ManagedObjectReference) { return $vCenter->makeBinaryGlobalMoRefUuid($value); - } else { - return $vCenter->makeBinaryGlobalUuid($value); } + + return $vCenter->makeBinaryGlobalUuid($value); } /** - * @return ManagedObject - * @throws \Icinga\Exception\NotFoundError + * @return ?ManagedObject + * + * @throws NotFoundError */ - public function object() + public function object(): ?ManagedObject { - if ($this->object === null) { - $this->object = ManagedObject::load($this->get('uuid'), $this->connection); - } - - return $this->object; + return $this->object ??= ManagedObject::load($this->get('uuid'), $this->connection); } - public function setManagedObject(?ManagedObject $object) + /** + * @param ?ManagedObject $object + * + * @return void + */ + public function setManagedObject(?ManagedObject $object): void { if ($object === null) { $this->object = null; + return; } if ($object->get('uuid') !== $this->get('uuid')) { - throw new \InvalidArgumentException(sprintf( + throw new InvalidArgumentException(sprintf( 'Cannot set ManagedObject UUID %s, expected %s', Uuid::fromBytes($object->get('uuid'))->toString(), Uuid::fromBytes($this->get('uuid'))->toString() @@ -186,17 +218,22 @@ public function setManagedObject(?ManagedObject $object) $this->object = $object; } - public static function getType() + /** + * @return false|string + */ + public static function getType(): false|string { $parts = explode('\\', get_class(static::create())); + return end($parts); } /** * @param VCenter $vCenter + * * @return static[] */ - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); $connection = $vCenter->getConnection(); diff --git a/library/Vspheredb/DbObject/BaseVmHardwareDbObject.php b/library/Vspheredb/DbObject/BaseVmHardwareDbObject.php index 36737150..7a7d14c2 100644 --- a/library/Vspheredb/DbObject/BaseVmHardwareDbObject.php +++ b/library/Vspheredb/DbObject/BaseVmHardwareDbObject.php @@ -4,9 +4,9 @@ abstract class BaseVmHardwareDbObject extends BaseDbObject { - protected $keyName = ['vm_uuid', 'hardware_key']; + protected string|array|null $keyName = ['vm_uuid', 'hardware_key']; - public function setMapped($properties, VCenter $vCenter) + public function setMapped($properties, VCenter $vCenter): static { $properties = (object) $properties; $this->set('vcenter_uuid', $vCenter->get('uuid')); @@ -31,11 +31,7 @@ public function setMapped($properties, VCenter $vCenter) return $this; } - /** - * @param VCenter $vCenter - * @return static[] - */ - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); $objects = static::loadAll( diff --git a/library/Vspheredb/DbObject/ComputeCluster.php b/library/Vspheredb/DbObject/ComputeCluster.php index c92e334b..25245b50 100644 --- a/library/Vspheredb/DbObject/ComputeCluster.php +++ b/library/Vspheredb/DbObject/ComputeCluster.php @@ -4,12 +4,12 @@ class ComputeCluster extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; // TODO: protected $table = 'compute_cluster'; - protected $table = 'object'; + protected ?string $table = 'object'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'moref' => null, @@ -18,11 +18,10 @@ class ComputeCluster extends BaseDbObject 'overall_status' => null, 'level' => null, 'parent_uuid' => null, - 'tags' => null, + 'tags' => null ]; - protected $propertyMap = [ - ]; + protected array $propertyMap = []; public function calculateStats() { @@ -43,7 +42,10 @@ public function calculateStats() ); } - public function countHosts() + /** + * @return false|string|null + */ + public function countHosts(): false|string|null { $db = $this->getDb(); return $db->fetchOne( diff --git a/library/Vspheredb/DbObject/ComputeResource.php b/library/Vspheredb/DbObject/ComputeResource.php index fbbfca74..806b4c3e 100644 --- a/library/Vspheredb/DbObject/ComputeResource.php +++ b/library/Vspheredb/DbObject/ComputeResource.php @@ -4,11 +4,11 @@ class ComputeResource extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'compute_resource'; + protected ?string $table = 'compute_resource'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'effective_cpu_mhz' => null, @@ -18,10 +18,10 @@ class ComputeResource extends BaseDbObject 'effective_hosts' => null, 'hosts' => null, 'total_cpu_mhz' => null, - 'total_memory_size_mb' => null, + 'total_memory_size_mb' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'summary.effectiveCpu' => 'effective_cpu_mhz', 'summary.effectiveMemory' => 'effective_memory_size_mb', 'summary.numCpuCores' => 'cpu_cores', @@ -30,6 +30,6 @@ class ComputeResource extends BaseDbObject 'summary.numHosts' => 'hosts', // 'summary.overallStatus' => '', 'summary.totalCpu' => 'total_cpu_mhz', - 'summary.totalMemory' => 'total_memory_size_mb', + 'summary.totalMemory' => 'total_memory_size_mb' ]; } diff --git a/library/Vspheredb/DbObject/CustomValueSupport.php b/library/Vspheredb/DbObject/CustomValueSupport.php index 50e8ba56..22e0b3b4 100644 --- a/library/Vspheredb/DbObject/CustomValueSupport.php +++ b/library/Vspheredb/DbObject/CustomValueSupport.php @@ -2,28 +2,28 @@ namespace Icinga\Module\Vspheredb\DbObject; +use gipfl\Json\JsonEncodeException; use gipfl\Json\JsonString; trait CustomValueSupport { /** - * @param $value - * @throws \gipfl\Json\JsonEncodeException + * @param mixed $value + * + * @return void + * + * @throws JsonEncodeException */ - protected function setCustomValues($value) + protected function setCustomValues(mixed $value): void { - if ($value === null) { - $this->set('custom_values', null); - } else { - $this->set('custom_values', JsonString::encode($value)); - } + $this->set('custom_values', $value === null ? null : JsonString::encode($value)); } /** * @return CustomValues */ - public function customValues() + public function customValues(): CustomValues { return CustomValues::fromJson($this->get('custom_values')); } diff --git a/library/Vspheredb/DbObject/CustomValues.php b/library/Vspheredb/DbObject/CustomValues.php index 29775c5c..53655a2e 100644 --- a/library/Vspheredb/DbObject/CustomValues.php +++ b/library/Vspheredb/DbObject/CustomValues.php @@ -4,29 +4,48 @@ use gipfl\Json\JsonString; use JsonSerializable; +use ReturnTypeWillChange; class CustomValues implements JsonSerializable { - protected $values = []; + protected array $values = []; - public static function create(?array $values = null) + /** + * @param ?array $values + * + * @return static + */ + public static function create(?array $values = null): static { return new static($values); } - public static function fromJson($string) + /** + * @param ?string $string $string + * + * @return static + */ + public static function fromJson(?string $string): static { return new static((array) JsonString::decodeOptional($string)); } - public function isEmpty() + /** + * @return bool + */ + public function isEmpty(): bool { return empty($this->values); } - public function has($key) + /** + * @param string $key + * + * @return bool + */ + public function has(string $key): bool { - return \array_key_exists($key, $this->values); + return array_key_exists($key, $this->values); } /** @@ -41,47 +60,56 @@ public function remove(string $key): void /** * @param string $key - * @param $value + * @param mixed $value * * @return void */ - public function set(string $key, $value): void + public function set(string $key, mixed $value): void { $this->values[$key] = $value; } /** * @param string $key - * @param $default + * @param mixed $default * - * @return mixed|null + * @return ?mixed */ - public function get(string $key, $default = null): mixed + public function get(string $key, mixed $default = null): mixed { if ($this->has($key)) { return $this->values[$key]; - } else { - return $default; } + + return $default; } - #[\ReturnTypeWillChange] - public function jsonSerialize() + #[ReturnTypeWillChange] + /** + * @return object + */ + public function jsonSerialize(): object { return (object) $this->values; } - public function toArray() + /** + * @return array + */ + public function toArray(): array { return $this->values; } + /** + * @param ?array $values + */ protected function __construct(?array $values = null) { if ($values === null) { return; - } else { - $this->values = $values; } + + $this->values = $values; } } diff --git a/library/Vspheredb/DbObject/Datastore.php b/library/Vspheredb/DbObject/Datastore.php index 5dbeda5f..062597ac 100644 --- a/library/Vspheredb/DbObject/Datastore.php +++ b/library/Vspheredb/DbObject/Datastore.php @@ -4,11 +4,11 @@ class Datastore extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'datastore'; + protected ?string $table = 'datastore'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'maintenance_mode' => null, @@ -18,16 +18,16 @@ class Datastore extends BaseDbObject 'uncommitted' => null, 'is_accessible' => null, 'multiple_host_access' => null, - 'ts_last_forced_refresh' => null, + 'ts_last_forced_refresh' => null ]; - protected $booleanProperties = [ + protected array $booleanProperties = [ 'is_accessible', 'multiple_host_access', 'ssd' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'summary.maintenanceMode' => 'maintenance_mode', // "normal" 'summary.accessible' => 'is_accessible', 'summary.freeSpace' => 'free_space', diff --git a/library/Vspheredb/DbObject/DbProperty.php b/library/Vspheredb/DbObject/DbProperty.php index 3b2a00c7..45d921d5 100644 --- a/library/Vspheredb/DbObject/DbProperty.php +++ b/library/Vspheredb/DbObject/DbProperty.php @@ -7,42 +7,32 @@ class DbProperty { /** - * @param ?boolean $value - * @return null|string + * @param ?bool $value + * + * @return ?string */ - public static function booleanToDb($value) + public static function booleanToDb(?bool $value): ?string { - if ($value === true) { - return 'y'; - } elseif ($value === false) { - return 'n'; - } elseif ($value === null) { - return null; - } else { - throw new InvalidArgumentException( - 'Boolean expected, got %s', - var_export($value, 1) - ); - } + return match ($value) { + true => 'y', + false => 'n', + null => null, + default => throw new InvalidArgumentException(sprintf('Boolean expected, got %s', var_export($value, 1))) + }; } /** * @param ?string $value - * @return bool|null + * + * @return ?bool */ - public static function dbToBoolean($value) + public static function dbToBoolean(?string $value): ?bool { - if ($value === 'y') { - return true; - } elseif ($value === 'n') { - return false; - } elseif ($value === null) { - return null; - } else { - throw new InvalidArgumentException( - 'Boolean expected, got %s', - var_export($value, 1) - ); - } + return match ($value) { + 'y' => true, + 'n' => false, + null => null, + default => throw new InvalidArgumentException(sprintf('Boolean expected, got %s', var_export($value, 1))) + }; } } diff --git a/library/Vspheredb/DbObject/DistributedVirtualPortgroup.php b/library/Vspheredb/DbObject/DistributedVirtualPortgroup.php index 6c70c159..4e379e59 100644 --- a/library/Vspheredb/DbObject/DistributedVirtualPortgroup.php +++ b/library/Vspheredb/DbObject/DistributedVirtualPortgroup.php @@ -6,39 +6,49 @@ class DistributedVirtualPortgroup extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'distributed_virtual_portgroup'; + protected ?string $table = 'distributed_virtual_portgroup'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'portgroup_type' => null, 'distributed_virtual_switch_uuid' => null, 'vlan' => null, 'vlan_ranges' => null, - 'num_ports' => null, + 'num_ports' => null ]; - protected $objectReferences = [ + protected array $objectReferences = [ 'distributed_virtual_switch_uuid' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'config.defaultPortConfig' => 'defaultPortConfig', 'config.numPorts' => 'num_ports', 'config.type' => 'portgroup_type', - 'config.distributedVirtualSwitch' => 'distributed_virtual_switch_uuid', + 'config.distributedVirtualSwitch' => 'distributed_virtual_switch_uuid' ]; - protected function setDefaultPortConfig($config) + /** + * @param object $config + * + * @return void + */ + protected function setDefaultPortConfig(object $config): void { if (property_exists($config, 'vlan')) { $this->setDefaultVlan($config->vlan->vlanId); } } - protected function setDefaultVlan($vlan) + /** + * @param mixed $vlan + * + * @return void + */ + protected function setDefaultVlan(mixed $vlan): void { if (is_array($vlan)) { $ranges = []; @@ -46,7 +56,7 @@ protected function setDefaultVlan($vlan) foreach ($vlan as $range) { $ranges[] = (object) [ 'end' => $range->end, - 'start' => $range->start, + 'start' => $range->start ]; } $this->set('vlan_ranges', json_encode($ranges)); diff --git a/library/Vspheredb/DbObject/DistributedVirtualSwitch.php b/library/Vspheredb/DbObject/DistributedVirtualSwitch.php index f3a36139..6e0dcd30 100644 --- a/library/Vspheredb/DbObject/DistributedVirtualSwitch.php +++ b/library/Vspheredb/DbObject/DistributedVirtualSwitch.php @@ -10,11 +10,11 @@ */ class DistributedVirtualSwitch extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'distributed_virtual_switch'; + protected ?string $table = 'distributed_virtual_switch'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'description' => null, @@ -23,10 +23,10 @@ class DistributedVirtualSwitch extends BaseDbObject 'max_ports' => null, 'hostmembers_checksum' => null, 'portgroups_checksum' => null, - 'vms_checksum' => null, + 'vms_checksum' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ // 'portgroup' => 'portGroups', 'config.description' => 'description', // config.uuid? @@ -35,56 +35,51 @@ class DistributedVirtualSwitch extends BaseDbObject 'summary.numHosts' => 'num_hosts', 'config.numPorts' => 'num_ports', 'config.maxPorts' => 'max_ports', - 'config.uplinkPortgroup' => 'uplinkPortGroups', + 'config.uplinkPortgroup' => 'uplinkPortGroups' ]; - protected $unstoredPortGroupRefs; + protected ?array $unstoredPortGroupRefs = null; - public function setUplinkPortGroups($portGroups) + /** + * @param array $portGroups + * + * @return void + */ + public function setUplinkPortGroups(array $portGroups): void { var_dump('UPLINK'); var_dump($portGroups); } - public function XXXXsetPortGroups($portGroups) - { - $newSum = $this->calculateMorefsChecksum($portGroups); - if ($this->get('portgroups_checksum') !== $newSum) { - $this->scheduleNewPortgroupRefs($portGroups); - } - } - /** * @param ManagedObjectReference[] $hostMembers + * + * @return void */ - public function setHostMembers($hostMembers) + public function setHostMembers(array $hostMembers): void { var_dump('HOSTMEMBERS'); var_dump($hostMembers); - return; - $newSum = $this->calculateMorefsChecksum($hostMembers); - if ($this->get('hostmembers_checksum') !== $newSum) { - $this->scheduleNewPortgroupRefs($hostMembers); - } } - protected function scheduleNewPortgroupRefs($portGroups) + /** + * @param array $portGroups + * + * @return void + */ + protected function scheduleNewPortgroupRefs(array $portGroups): void { $this->unstoredPortGroupRefs = $portGroups; } - protected function onStore() - { - if (false && $this->unstoredPortGroupRefs) { - $this->replaceMoRefs( - $this->get('uuid'), - 'distributed_switch_portgroup', - $this->unstoredPortGroupRefs - ); - } - } - - protected function replaceMoRefs($uuid, $table, $refs) + /** + * @param string $uuid + * @param string $table + * @param array $refs + * + * @return void + */ + protected function replaceMoRefs(string $uuid, string $table, array $refs): void { // TODO: WHAAAAAAAAAAAAAAT? $vCenter = VCenter::loadWithAutoIncId(1, $this->getConnection()); @@ -101,7 +96,12 @@ protected function replaceMoRefs($uuid, $table, $refs) } } - protected function calculateMorefsChecksum($moRefs) + /** + * @param array $moRefs + * + * @return string + */ + protected function calculateMorefsChecksum(array $moRefs): string { $names = []; foreach ($moRefs as $moRef) { @@ -109,6 +109,7 @@ protected function calculateMorefsChecksum($moRefs) } sort($names); + return sha1(implode('|', $names), true); } } diff --git a/library/Vspheredb/DbObject/HostHba.php b/library/Vspheredb/DbObject/HostHba.php index 365fd067..0e4d04c0 100644 --- a/library/Vspheredb/DbObject/HostHba.php +++ b/library/Vspheredb/DbObject/HostHba.php @@ -4,11 +4,11 @@ class HostHba extends BaseVmHardwareDbObject { - protected $keyName = ['host_uuid', 'hba_key']; + protected string|array|null $keyName = ['host_uuid', 'hba_key']; - protected $table = 'host_hba'; + protected ?string $table = 'host_hba'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'host_uuid' => null, 'hba_key' => null, 'device' => null, @@ -18,16 +18,16 @@ class HostHba extends BaseVmHardwareDbObject 'pci' => null, 'status' => null, 'storage_protocol' => 'scsi', - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'device' => 'device', 'bus' => 'bus', 'driver' => 'driver', 'model' => 'model', 'pci' => 'pci', 'status' => 'status', - 'storageProtocol' => 'storage_protocol', + 'storageProtocol' => 'storage_protocol' ]; } diff --git a/library/Vspheredb/DbObject/HostPciDevice.php b/library/Vspheredb/DbObject/HostPciDevice.php index d50f9527..3c86f452 100644 --- a/library/Vspheredb/DbObject/HostPciDevice.php +++ b/library/Vspheredb/DbObject/HostPciDevice.php @@ -2,11 +2,13 @@ namespace Icinga\Module\Vspheredb\DbObject; +use Icinga\Exception\IcingaException; + class HostPciDevice extends BaseDbObject { - protected $table = 'host_pci_device'; + protected ?string $table = 'host_pci_device'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'id' => null, 'host_uuid' => null, 'bus' => null, @@ -20,14 +22,14 @@ class HostPciDevice extends BaseDbObject 'vendor_name' => null, 'sub_vendor_id' => null, 'parent_bridge' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $objectReferences = [ - 'host_uuid', + protected array $objectReferences = [ + 'host_uuid' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'id' => 'id', 'bus' => 'bus', 'slot' => 'slot', @@ -39,12 +41,12 @@ class HostPciDevice extends BaseDbObject 'vendorId' => 'vendor_id', 'vendorName' => 'vendor_name', 'subVendorId' => 'sub_vendor_id', - 'parentBridge' => 'parent_bridge', + 'parentBridge' => 'parent_bridge' ]; - protected $keyName = ['host_uuid', 'id']; + protected string|array|null $keyName = ['host_uuid', 'id']; - public function setMapped($properties, VCenter $vCenter) + public function setMapped(object $properties, VCenter $vCenter): static { $this->set('vcenter_uuid', $vCenter->get('uuid')); @@ -58,6 +60,7 @@ public function setMapped($properties, VCenter $vCenter) var_dump(is_int($properties->$key)); var_dump($properties->$key); var_dump($properties); + exit; } } else { @@ -73,10 +76,12 @@ public function setMapped($properties, VCenter $vCenter) /** * @param VCenter $vCenter + * * @return static[] - * @throws \Icinga\Exception\IcingaException + * + * @throws IcingaException */ - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); $objects = static::loadAll( diff --git a/library/Vspheredb/DbObject/HostPhysicalNic.php b/library/Vspheredb/DbObject/HostPhysicalNic.php index 91e2d585..0337f35e 100644 --- a/library/Vspheredb/DbObject/HostPhysicalNic.php +++ b/library/Vspheredb/DbObject/HostPhysicalNic.php @@ -4,11 +4,11 @@ class HostPhysicalNic extends BaseVmHardwareDbObject { - protected $keyName = ['host_uuid', 'nic_key']; + protected string|array|null $keyName = ['host_uuid', 'nic_key']; - protected $table = 'host_physical_nic'; + protected ?string $table = 'host_physical_nic'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'host_uuid' => null, 'nic_key' => null, 'auto_negotiate_supported' => null, @@ -18,21 +18,21 @@ class HostPhysicalNic extends BaseVmHardwareDbObject 'link_duplex' => null, 'mac_address' => null, 'pci' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'device' => 'device', 'driver' => 'driver', 'pci' => 'pci', 'linkSpeed.speedMb' => 'link_speed_mb', 'linkSpeed.duplex' => 'link_duplex', 'mac' => 'mac_address', - 'autoNegotiateSupported' => 'auto_negotiate_supported', + 'autoNegotiateSupported' => 'auto_negotiate_supported' ]; - protected $booleanProperties = [ + protected array $booleanProperties = [ 'auto_negotiate_supported', - 'link_duplex', + 'link_duplex' ]; } diff --git a/library/Vspheredb/DbObject/HostQuickStats.php b/library/Vspheredb/DbObject/HostQuickStats.php index c5062da9..76dccf48 100644 --- a/library/Vspheredb/DbObject/HostQuickStats.php +++ b/library/Vspheredb/DbObject/HostQuickStats.php @@ -6,41 +6,55 @@ class HostQuickStats extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'host_quick_stats'; + protected ?string $table = 'host_quick_stats'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'distributed_cpu_fairness' => null, 'distributed_memory_fairness' => null, 'overall_cpu_usage' => null, 'overall_memory_usage_mb' => null, 'uptime' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'summary.quickStats.distributedCpuFairness' => 'distributed_cpu_fairness', 'summary.quickStats.distributedMemoryFairness' => 'distributed_memory_fairness', 'summary.quickStats.overallCpuUsage' => 'overall_cpu_usage', 'summary.quickStats.overallMemoryUsage' => 'overall_memory_usage_mb', - 'summary.quickStats.uptime' => 'uptime', + 'summary.quickStats.uptime' => 'uptime' ]; - protected static $preloadCache = null; + /** @var ?static[] */ + protected static ?array $preloadCache = null; - public static function preloadAll(Db $db) + /** + * @param Db $db + * + * @return void + */ + public static function preloadAll(Db $db): void { self::$preloadCache = self::loadAll($db, null, 'uuid'); } - public static function clearPreloadCache() + /** + * @return void + */ + public static function clearPreloadCache(): void { self::$preloadCache = null; } - public static function loadFor(HostSystem $object) + /** + * @param HostSystem $object + * + * @return static + */ + public static function loadFor(HostSystem $object): static { if ($object->hasBeenLoadedFromDb()) { $connection = $object->getConnection(); diff --git a/library/Vspheredb/DbObject/HostSensor.php b/library/Vspheredb/DbObject/HostSensor.php index b8ef19d6..0ac8c542 100644 --- a/library/Vspheredb/DbObject/HostSensor.php +++ b/library/Vspheredb/DbObject/HostSensor.php @@ -4,9 +4,9 @@ class HostSensor extends BaseDbObject { - protected $table = 'host_sensor'; + protected ?string $table = 'host_sensor'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'name' => null, 'host_uuid' => null, 'health_state' => null, @@ -15,27 +15,32 @@ class HostSensor extends BaseDbObject 'base_units' => null, 'rate_units' => null, 'sensor_type' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $objectReferences = [ - 'host_uuid', + protected array $objectReferences = [ + 'host_uuid' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'name' => 'name', 'healthState' => 'health_state', 'currentReading' => 'current_reading', 'unitModifier' => 'unit_modifier', 'baseUnits' => 'base_units', 'rateUnits' => 'rate_units', - 'sensorType' => 'sensor_type', + 'sensorType' => 'sensor_type' ]; // TODO: HostNumericSensorInfo has 'id' since v6.5 - protected $keyName = ['host_uuid', 'name']; + protected string|array|null $keyName = ['host_uuid', 'name']; - public function setName($value) + /** + * @param string $value + * + * @return static + */ + public function setName(string $value): static { // name has the form "description --- state/identifier" // TODO: strip the identifier once we changed the key to 'id' @@ -43,25 +48,17 @@ public function setName($value) // $value = \preg_replace('/\s---\s.+$/', '', $value); if ($value === $this->get('name')) { return $this; - } else { - return $this->reallySet('name', $value); } + + return $this->reallySet('name', $value); } - public function setHealth_state($healthState) // phpcs:ignore + public function setHealth_state($healthState): void // phpcs:ignore { - if (is_object($healthState)) { - $this->reallySet('health_state', lcfirst($healthState->key)); - } else { - $this->reallySet('health_state', $healthState); - } + $this->reallySet('health_state', is_object($healthState) ? lcfirst($healthState->key) : $healthState); } - /** - * @param VCenter $vCenter - * @return static[] - */ - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); $objects = static::loadAll( diff --git a/library/Vspheredb/DbObject/HostSystem.php b/library/Vspheredb/DbObject/HostSystem.php index 83e157a4..b5c10644 100644 --- a/library/Vspheredb/DbObject/HostSystem.php +++ b/library/Vspheredb/DbObject/HostSystem.php @@ -4,16 +4,17 @@ use DateTime; use Icinga\Module\Vspheredb\MappedClass\ClusterDasFdmHostState; +use stdClass; class HostSystem extends BaseDbObject { use CustomValueSupport; - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'host_system'; + protected ?string $table = 'host_system'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'host_name' => null, @@ -35,10 +36,10 @@ class HostSystem extends BaseDbObject 'hardware_num_nic' => null, 'runtime_power_state' => null, 'das_host_state' => null, - 'custom_values' => null, + 'custom_values' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ // config.fileSystemVolume.mountInfo 'name' => 'host_name', 'summary.config.product.apiVersion' => 'product_api_version', @@ -60,10 +61,13 @@ class HostSystem extends BaseDbObject 'summary.hardware.cpuMhz' => 'hardware_cpu_mhz', 'summary.hardware.cpuModel' => 'hardware_cpu_model', 'summary.hardware.numHBAs' => 'hardware_num_hba', - 'summary.hardware.numNics' => 'hardware_num_nic', + 'summary.hardware.numNics' => 'hardware_num_nic' ]; - public function countVms() + /** + * @return string + */ + public function countVms(): string { $db = $this->getDb(); return $db->fetchOne( @@ -73,7 +77,7 @@ public function countVms() ); } - public function setMapped($properties, VCenter $vCenter) + public function setMapped(object $properties, VCenter $vCenter): static { $otherInfo = $properties->{'summary.hardware.otherIdentifyingInfo'}; if (property_exists($otherInfo, 'HostSystemIdentificationInfo')) { @@ -95,7 +99,12 @@ public function setMapped($properties, VCenter $vCenter) return parent::setMapped($properties, $vCenter); } - protected function setOtherIdentifyingInfo($infos) + /** + * @param mixed $infos + * + * @return void + */ + protected function setOtherIdentifyingInfo(mixed $infos): void { foreach ($infos as $info) { if ($info->identifierType->key === 'ServiceTag') { @@ -107,17 +116,22 @@ protected function setOtherIdentifyingInfo($infos) } } - protected function setDasHostState($state = null) + /** + * @param ClusterDasFdmHostState|stdClass|null $state + * + * @return void + */ + protected function setDasHostState(ClusterDasFdmHostState|stdClass|null $state = null): void { - if ($state === null) { - $this->set('das_host_state', null); - } else { - /** @var ClusterDasFdmHostState|\stdClass $state */ - $this->set('das_host_state', $state->state); - } + $this->set('das_host_state', $state?->state); } - protected function formatBiosReleaseDate($date) + /** + * @param string $date + * + * @return string + */ + protected function formatBiosReleaseDate(string $date): string { return (new DateTime($date))->format('Y-m-d H:i:s'); } diff --git a/library/Vspheredb/DbObject/HostVirtualNic.php b/library/Vspheredb/DbObject/HostVirtualNic.php index eda20cd8..cdd4e2ae 100644 --- a/library/Vspheredb/DbObject/HostVirtualNic.php +++ b/library/Vspheredb/DbObject/HostVirtualNic.php @@ -4,11 +4,11 @@ class HostVirtualNic extends BaseVmHardwareDbObject { - protected $keyName = ['host_uuid', 'nic_key']; + protected string|array|null $keyName = ['host_uuid', 'nic_key']; - protected $table = 'host_virtual_nic'; + protected ?string $table = 'host_virtual_nic'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'host_uuid' => null, 'nic_key' => null, 'net_stack_instance_key' => null, @@ -31,10 +31,10 @@ class HostVirtualNic extends BaseVmHardwareDbObject // pinnedPnic? 'device' => null, 'tso_enabled' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'device' => 'device', 'port' => 'port', 'portgroup' => 'portgroup', @@ -52,6 +52,6 @@ class HostVirtualNic extends BaseVmHardwareDbObject 'spec.distributedVirtualPort.ip.ipV6Config.origin' => 'ipv6_origin', */ 'spec.mac' => 'mac_address', - 'spec.distributedVirtualPort.tsoEnabled' => 'tso_enabled', + 'spec.distributedVirtualPort.tsoEnabled' => 'tso_enabled' ]; } diff --git a/library/Vspheredb/DbObject/ManagedObject.php b/library/Vspheredb/DbObject/ManagedObject.php index 01cb63fe..d3f5ec6a 100644 --- a/library/Vspheredb/DbObject/ManagedObject.php +++ b/library/Vspheredb/DbObject/ManagedObject.php @@ -2,19 +2,21 @@ namespace Icinga\Module\Vspheredb\DbObject; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Db\DbObject as VspheredbDbObject; use Icinga\Module\Vspheredb\Db\DbUtil; +use Icinga\Module\Vspheredb\Exception\DuplicateKeyException; use Ramsey\Uuid\Uuid; use RuntimeException; class ManagedObject extends VspheredbDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'object'; + protected ?string $table = 'object'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'moref' => null, @@ -23,33 +25,32 @@ class ManagedObject extends VspheredbDbObject 'overall_status' => null, 'level' => null, 'parent_uuid' => null, - 'tags' => null, + 'tags' => null ]; - /** @var ManagedObject */ - private $parent; + private ?ManagedObject $parent = null; /** * @param string $uuid * @param Db $connection + * * @return static - * @throws \Icinga\Exception\NotFoundError + * + * @throws NotFoundError */ public static function loadWithUuid(string $uuid, Db $connection): ManagedObject { - if (strlen($uuid) === 16) { - $uuid = Uuid::fromBytes($uuid); - } else { - $uuid = Uuid::fromString($uuid); - } + $uuid = strlen($uuid) === 16 ? Uuid::fromBytes($uuid) : Uuid::fromString($uuid); return static::load($uuid->getBytes(), $connection); } /** - * @throws \Icinga\Module\Vspheredb\Exception\DuplicateKeyException + * @returns void + * + * @throws DuplicateKeyException */ - protected function beforeStore() + protected function beforeStore(): void { if (null !== $this->parent) { $this->parent->store(); @@ -62,30 +63,38 @@ protected function beforeStore() $this->set('level', $this->calculateLevel()); } - public function getBinaryUuid() + /** + * @return mixed + */ + public function getBinaryUuid(): mixed { return $this->get('uuid'); } - public function setParent(ManagedObject $object) + /** + * @param ManagedObject $object + * + * @return $this + */ + public function setParent(ManagedObject $object): static { $this->parent = $object; // Hint: parent change hasn't been detected otherwise. // TODO: check whether change detection is still fine - if ($object->hasBeenLoadedFromDb()) { - $this->set('parent_uuid', $object->get('uuid')); - } else { - $this->set('parent_uuid', 'NOT YET, SETTING A TOO LONG STRING'); - } + $this->set( + 'parent_uuid', + $object->hasBeenLoadedFromDb() ? $object->get('uuid') : 'NOT YET, SETTING A TOO LONG STRING' + ); return $this; } /** * @param VCenter $vCenter + * * @return static[] */ - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); @@ -100,7 +109,10 @@ public static function loadAllForVCenter(VCenter $vCenter) ); } - public function getNumericLevel() + /** + * @return int + */ + public function getNumericLevel(): int { $level = $this->get('level'); if ($level === null) { @@ -110,18 +122,22 @@ public function getNumericLevel() return (int) $level; } - public function calculateLevel() + /** + * @return int + */ + public function calculateLevel(): int { - if ($this->parent === null) { - return 0; - } else { - return $this->parent->calculateLevel() + 1; - } + return $this->parent === null ? 0 : $this->parent->calculateLevel() + 1; } - protected function isBinaryColumn($column) + /** + * @param string $column + * + * @return bool + */ + protected function isBinaryColumn(string $column): bool { - if ($column === 'uuid' || substr($column, -5) === '_uuid') { + if ($column === 'uuid' || str_ends_with($column, '_uuid')) { return true; } diff --git a/library/Vspheredb/DbObject/MappingHelper.php b/library/Vspheredb/DbObject/MappingHelper.php index ed88b21f..f1952376 100644 --- a/library/Vspheredb/DbObject/MappingHelper.php +++ b/library/Vspheredb/DbObject/MappingHelper.php @@ -16,12 +16,12 @@ class MappingHelper * and a key vars.disk.sda given as [ 'vars', 'disk', 'sda' ] this would * return { size => '255GB' } * - * @param string $val The value to extract data from - * @param array $keys A list of nested keys pointing to desired data + * @param object|string|null $val The value to extract data from + * @param array $keys A list of nested keys pointing to desired data * * @return mixed */ - public static function getDeepValue($val, array $keys) + public static function getDeepValue(object|string|null $val, array $keys): mixed { if ($val === null) { return null; @@ -43,13 +43,14 @@ public static function getDeepValue($val, array $keys) * * Supports also keys pointing to nested structures like vars.disk.sda * - * @param object $row stdClass object providing property values - * @param string $var Variable/property name + * @param object $row stdClass object providing property values + * @param string $var Variable/property name + * * @return mixed */ - public static function getSpecificValue($row, $var) + public static function getSpecificValue(object $row, string $var): mixed { - if (strpos($var, '.') === false) { + if (! str_contains($var, '.')) { if ($row instanceof DbObject) { return $row->$var; } diff --git a/library/Vspheredb/DbObject/MoRefList.php b/library/Vspheredb/DbObject/MoRefList.php index 6e1f10cf..1b5b7bbc 100644 --- a/library/Vspheredb/DbObject/MoRefList.php +++ b/library/Vspheredb/DbObject/MoRefList.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\DbObject; +use Exception; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; +use Zend_Db_Adapter_Exception; abstract class MoRefList { @@ -13,9 +15,10 @@ abstract class MoRefList /** * @param VCenter $vCenter * @param ManagedObjectReference[] $objects + * * @return string */ - public static function requireChecksum(VCenter $vCenter, $objects) + public static function requireChecksum(VCenter $vCenter, array $objects): string { $key = static::calculateChecksum($vCenter, $objects); @@ -27,11 +30,12 @@ public static function requireChecksum(VCenter $vCenter, $objects) } /** - * @param $checksum + * @param string $checksum * @param VCenter $vCenter + * * @return bool */ - protected static function checksumExists($checksum, VCenter $vCenter) + protected static function checksumExists(string $checksum, VCenter $vCenter): bool { $db = $vCenter->getDb(); return (int) $db->fetchOne( @@ -42,11 +46,13 @@ protected static function checksumExists($checksum, VCenter $vCenter) } /** - * @param $checksum + * @param string $checksum * @param ManagedObjectReference[] $objects * @param VCenter $vCenter + * + * @return void */ - protected static function create($checksum, $objects, VCenter $vCenter) + protected static function create(string $checksum, array $objects, VCenter $vCenter): void { $db = $vCenter->getDb(); $db->beginTransaction(); @@ -61,10 +67,10 @@ protected static function create($checksum, $objects, VCenter $vCenter) ]); } $db->commit(); - } catch (\Zend_Db_Adapter_Exception $e) { + } catch (Zend_Db_Adapter_Exception $e) { try { $db->rollBack(); - } catch (\Exception $e) { + } catch (Exception $e) { // There is nothing we can do about this } @@ -75,9 +81,10 @@ protected static function create($checksum, $objects, VCenter $vCenter) /** * @param VCenter $vCenter * @param ManagedObjectReference[] $objects + * * @return string */ - protected static function calculateChecksum(VCenter $vCenter, $objects) + protected static function calculateChecksum(VCenter $vCenter, array $objects): string { $list = []; foreach ($objects as $object) { diff --git a/library/Vspheredb/DbObject/MonitoringConnection.php b/library/Vspheredb/DbObject/MonitoringConnection.php index fd8b1cc5..f8311c8a 100644 --- a/library/Vspheredb/DbObject/MonitoringConnection.php +++ b/library/Vspheredb/DbObject/MonitoringConnection.php @@ -3,17 +3,19 @@ namespace Icinga\Module\Vspheredb\DbObject; use Icinga\Exception\ConfigurationError; +use Icinga\Exception\NotFoundError; use Icinga\Module\Monitoring\Backend\MonitoringBackend; use Icinga\Module\Vspheredb\Ido; use RuntimeException; +use Zend_Db_Adapter_Abstract; class MonitoringConnection extends BaseDbObject { - protected $keyName = 'id'; + protected string|array|null $keyName = 'id'; - protected $table = 'monitoring_connection'; + protected ?string $table = 'monitoring_connection'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'id' => null, 'vcenter_uuid' => null, 'priority' => null, @@ -22,38 +24,42 @@ class MonitoringConnection extends BaseDbObject 'host_property' => null, 'monitoring_host_property' => null, 'vm_property' => null, - 'monitoring_vm_host_property' => null, + 'monitoring_vm_host_property' => null ]; - protected $monitoring; + protected ?Ido $monitoring = null; /** * @param VCenter $vCenter - * @return Ido|null - * @throws \Icinga\Exception\NotFoundError + * + * @return ?Ido + * + * @throws NotFoundError */ - public static function eventuallyLoadForVCenter(VCenter $vCenter) + public static function eventuallyLoadForVCenter(VCenter $vCenter): ?Ido { $db = $vCenter->getConnection(); if (static::exists($vCenter->getUuid(), $db)) { - return static::load( - $vCenter->getUuid(), - $db - )->getMonitoring(); - } else { - return null; + return static::load($vCenter->getUuid(), $db)->getMonitoring(); } + + return null; } - public function getIdoDb() + /** + * @return Zend_Db_Adapter_Abstract + */ + public function getIdoDb(): Zend_Db_Adapter_Abstract { - /** @var \Icinga\Data\Db\DbConnection $resource */ - $resource = $this->getMonitoringBackend()->getResource(); - - return $resource->getDbAdapter(); + return $this->getMonitoringBackend()->getResource()->getDbAdapter(); } - public function getMonitoringBackend() + /** + * @return MonitoringBackend + * + * @throws RuntimeException + */ + public function getMonitoringBackend(): MonitoringBackend { $this->assertIdo(); @@ -64,7 +70,12 @@ public function getMonitoringBackend() } } - protected function assertIdo() + /** + * @return void + * + * @throws RuntimeException + */ + protected function assertIdo(): void { if ($this->get('source_type') !== 'ido') { throw new RuntimeException(sprintf( @@ -77,12 +88,8 @@ protected function assertIdo() /** * @return Ido */ - public function getMonitoring() + public function getMonitoring(): Ido { - if ($this->monitoring === null) { - $this->monitoring = Ido::createByResourceName($this->get('source_resource_name')); - } - - return $this->monitoring; + return $this->monitoring ??= Ido::createByResourceName($this->get('source_resource_name')); } } diff --git a/library/Vspheredb/DbObject/StoragePod.php b/library/Vspheredb/DbObject/StoragePod.php index 3d718ff0..da2849a0 100644 --- a/library/Vspheredb/DbObject/StoragePod.php +++ b/library/Vspheredb/DbObject/StoragePod.php @@ -4,21 +4,21 @@ class StoragePod extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'storage_pod'; + protected ?string $table = 'storage_pod'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'pod_name' => null, 'free_space' => null, - 'capacity' => null, + 'capacity' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'name' => 'pod_name', 'summary.capacity' => 'capacity', - 'summary.freeSpace' => 'free_space', + 'summary.freeSpace' => 'free_space' ]; } diff --git a/library/Vspheredb/DbObject/TaggingCategory.php b/library/Vspheredb/DbObject/TaggingCategory.php index f6fa74a6..f60e0562 100644 --- a/library/Vspheredb/DbObject/TaggingCategory.php +++ b/library/Vspheredb/DbObject/TaggingCategory.php @@ -5,26 +5,28 @@ class TaggingCategory extends BaseDbObject { public const TABLE = 'tagging_category'; - protected $keyName = 'uuid'; - protected $table = self::TABLE; - protected $defaultProperties = [ + protected string|array|null $keyName = 'uuid'; + + protected ?string $table = self::TABLE; + + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'id' => null, 'name' => null, 'cardinality' => null, 'description' => null, - 'associable_types' => null, + 'associable_types' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'uuid' => 'uuid', 'id' => 'id', 'name' => 'name', 'cardinality' => 'cardinality', 'description' => 'description', - 'associable_types' => 'associable_types', + 'associable_types' => 'associable_types' ]; public function cardinalityIsSingle(): bool diff --git a/library/Vspheredb/DbObject/TaggingObjectTag.php b/library/Vspheredb/DbObject/TaggingObjectTag.php index 2ff89d33..a5a28b96 100644 --- a/library/Vspheredb/DbObject/TaggingObjectTag.php +++ b/library/Vspheredb/DbObject/TaggingObjectTag.php @@ -6,18 +6,18 @@ class TaggingObjectTag extends BaseDbObject { public const TABLE = 'tagging_object_tag'; - protected $keyName = ['object_uuid', 'tag_uuid']; + protected string|array|null $keyName = ['object_uuid', 'tag_uuid']; - protected $table = self::TABLE; + protected ?string $table = self::TABLE; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'object_uuid' => null, 'tag_uuid' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'object_uuid' => 'object_uuid', - 'tag_uuid' => 'tag_uuid', + 'tag_uuid' => 'tag_uuid' ]; } diff --git a/library/Vspheredb/DbObject/TaggingTag.php b/library/Vspheredb/DbObject/TaggingTag.php index aed9da1a..338b1e1f 100644 --- a/library/Vspheredb/DbObject/TaggingTag.php +++ b/library/Vspheredb/DbObject/TaggingTag.php @@ -6,28 +6,28 @@ class TaggingTag extends BaseDbObject { public const TABLE = 'tagging_tag'; - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = self::TABLE; + protected ?string $table = self::TABLE; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'category_uuid' => null, 'vcenter_uuid' => null, 'id' => null, 'name' => null, - 'description' => null, + 'description' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'uuid' => 'uuid', 'category_uuid' => 'category_uuid', 'id' => 'id', 'name' => 'name', - 'description' => 'description', + 'description' => 'description' ]; - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); $connection = $vCenter->getConnection(); diff --git a/library/Vspheredb/DbObject/VCenter.php b/library/Vspheredb/DbObject/VCenter.php index 908ef213..b440f535 100644 --- a/library/Vspheredb/DbObject/VCenter.php +++ b/library/Vspheredb/DbObject/VCenter.php @@ -7,19 +7,21 @@ use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use RuntimeException; +use stdClass; /** * @method Db getConnection() */ class VCenter extends BaseDbObject { - protected $table = 'vcenter'; + protected ?string $table = 'vcenter'; - protected $keyName = 'instance_uuid'; + protected string|array|null $keyName = 'instance_uuid'; - protected $autoincKeyName = 'id'; + protected ?string $autoincKeyName = 'id'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'id' => null, 'instance_uuid' => null, 'trust_store_id' => null, @@ -35,10 +37,10 @@ class VCenter extends BaseDbObject 'license_product_name' => null, 'license_product_version' => null, 'locale_build' => null, - 'locale_version' => null, + 'locale_version' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'instanceUuid' => 'instance_uuid', 'name' => 'api_name', 'version' => 'version', @@ -51,57 +53,73 @@ class VCenter extends BaseDbObject 'licenseProductName' => 'license_product_name', 'licenseProductVersion' => 'license_product_version', 'localeBuild' => 'locale_build', - 'localeVersion' => 'locale_version', + 'localeVersion' => 'locale_version' ]; - public function getFullName() + /** + * @return string + */ + public function getFullName(): string { return sprintf( '%s %s build-%s', - \preg_replace('/^VMware /', '', $this->get('api_name')), + preg_replace('/^VMware /', '', $this->get('api_name')), $this->get('version'), $this->get('build') ); } - public function isHostAgent() + /** + * @return bool + */ + public function isHostAgent(): bool { return $this->get('api_type') === 'HostAgent'; } - public function isVirtualCenter() + /** + * @return bool + */ + public function isVirtualCenter(): bool { return $this->get('api_type') === 'VirtualCenter'; } - // TODO: Settle with one or the other. This should better give a UUID object - public function getUuid() + + /** + * TODO: Settle with one or the other. This should better give a UUID object + * + * @return mixed + */ + public function getUuid(): mixed { return $this->get('instance_uuid'); } - public function getBinaryUuid() + /** + * @return mixed + */ + public function getBinaryUuid(): mixed { return $this->get('instance_uuid'); } - public static function loadWithUuid(string $uuid, Db $connection) + public static function loadWithUuid(string $uuid, Db $connection): static { - if (strlen($uuid) === 16) { - $uuid = Uuid::fromBytes($uuid); - } else { - $uuid = Uuid::fromString($uuid); - } + $uuid = strlen($uuid) === 16 ? Uuid::fromBytes($uuid) : Uuid::fromString($uuid); return static::load($uuid->getBytes(), $connection); } /** * @param bool $enabled - * @return VCenterServer + * @param bool $required + * + * @return ?VCenterServer + * * @throws NotFoundError */ - public function getFirstServer($enabled = true, $required = true) + public function getFirstServer(bool $enabled = true, bool $required = true): ?VCenterServer { $db = $this->getConnection()->getDbAdapter(); $query = $db->select() @@ -122,49 +140,53 @@ public function getFirstServer($enabled = true, $required = true) ->limit(1) ); if ($serverId) { - throw new NotFoundError( - 'All server connections configured for this vCenter have been disabled' - ); - } else { - throw new NotFoundError( - 'Found no server for vCenterId=' . $this->get('id') - ); + throw new NotFoundError('All server connections configured for this vCenter have been disabled'); } + + throw new NotFoundError('Found no server for vCenterId=' . $this->get('id')); } elseif ($required) { - throw new NotFoundError( - 'Found no server for vCenterId=' . $this->get('id') - ); - } else { - return null; + throw new NotFoundError('Found no server for vCenterId=' . $this->get('id')); } + + return null; } - public function makeBinaryGlobalUuid($moRefId) + /** + * @param mixed $moRefId + * + * @return string + */ + public function makeBinaryGlobalUuid(mixed $moRefId): string { - if ($moRefId instanceof ManagedObjectReference || $moRefId instanceof \stdClass) { + if ($moRefId instanceof ManagedObjectReference || $moRefId instanceof stdClass) { return $this->makeBinaryGlobalMoRefUuid($moRefId); - } elseif (is_string($moRefId)) { + } + + if (is_string($moRefId)) { return Uuid::uuid5(Uuid::fromBytes($this->get('uuid')), $moRefId)->getBytes(); - } else { - throw new \RuntimeException('MoRef expected, got ' . gettype($moRefId)); } + + throw new RuntimeException('MoRef expected, got ' . gettype($moRefId)); } /** - * @param ManagedObjectReference|\stdClass $moRef + * @param stdClass|ManagedObjectReference $moRef + * * @return string */ - public function makeBinaryGlobalMoRefUuid($moRef): string + public function makeBinaryGlobalMoRefUuid(stdClass|ManagedObjectReference $moRef): string { return $this->makeBinaryGlobalMoRefUuidObject($moRef)->getBytes(); } /** - * @param ManagedObjectReference|\stdClass $moRef + * @param stdClass|ManagedObjectReference $moRef + * + * @return UuidInterface */ - public function makeBinaryGlobalMoRefUuidObject($moRef): UuidInterface + public function makeBinaryGlobalMoRefUuidObject(stdClass|ManagedObjectReference $moRef): UuidInterface { - if ($moRef instanceof \stdClass) { + if ($moRef instanceof stdClass) { $moRef = ManagedObjectReference::fromSerialization($moRef); } @@ -172,14 +194,12 @@ public function makeBinaryGlobalMoRefUuidObject($moRef): UuidInterface } /** - * @param $value + * @param string $value + * + * @return void */ - public function setInstance_uuid($value) // phpcs:ignore + public function setInstance_uuid(string $value): void // phpcs:ignore { - if (strlen($value) > 16) { - $this->reallySet('instance_uuid', Uuid::fromString($value)->getBytes()); - } else { - $this->reallySet('instance_uuid', $value); - } + $this->reallySet('instance_uuid', strlen($value) > 16 ? Uuid::fromString($value)->getBytes() : $value); } } diff --git a/library/Vspheredb/DbObject/VCenterServer.php b/library/Vspheredb/DbObject/VCenterServer.php index 1fb12688..bb894d43 100644 --- a/library/Vspheredb/DbObject/VCenterServer.php +++ b/library/Vspheredb/DbObject/VCenterServer.php @@ -6,11 +6,11 @@ class VCenterServer extends BaseDbObject { - protected $table = 'vcenter_server'; + protected ?string $table = 'vcenter_server'; - protected $autoincKeyName = 'id'; + protected ?string $autoincKeyName = 'id'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'id' => null, 'vcenter_id' => null, 'scheme' => null, @@ -23,14 +23,15 @@ class VCenterServer extends BaseDbObject 'proxy_pass' => null, 'ssl_verify_peer' => null, 'ssl_verify_host' => null, - 'enabled' => null, + 'enabled' => null ]; /** * @param Db $db + * * @return VCenterServer[] */ - public static function loadEnabledServers(Db $db) + public static function loadEnabledServers(Db $db): array { return static::loadAll( $db, diff --git a/library/Vspheredb/DbObject/VirtualMachine.php b/library/Vspheredb/DbObject/VirtualMachine.php index 0364b221..0ad21cfc 100644 --- a/library/Vspheredb/DbObject/VirtualMachine.php +++ b/library/Vspheredb/DbObject/VirtualMachine.php @@ -6,16 +6,18 @@ use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\MappedClass\GuestNicInfo; use Icinga\Module\Vspheredb\Util; +use InvalidArgumentException; +use stdClass; class VirtualMachine extends BaseDbObject { use CustomValueSupport; - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'virtual_machine'; + protected ?string $table = 'virtual_machine'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'vcenter_uuid' => null, 'annotation' => null, @@ -48,23 +50,23 @@ class VirtualMachine extends BaseDbObject 'cpu_hot_add_enabled' => null, 'memory_hot_add_enabled' => null, 'guest_ip_addresses' => null, - 'guest_ip_stack' => null, + 'guest_ip_stack' => null ]; - protected $objectReferences = [ + protected array $objectReferences = [ 'runtime_host_uuid', 'resource_pool_uuid' ]; - protected $booleanProperties = [ + protected array $booleanProperties = [ 'template', 'online_standby', 'paused', 'cpu_hot_add_enabled', - 'memory_hot_add_enabled', + 'memory_hot_add_enabled' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'config.annotation' => 'annotation', // TODO: Delegate to vm_hardware sync? 'config.hardware.memoryMB' => 'hardware_memorymb', @@ -97,12 +99,14 @@ class VirtualMachine extends BaseDbObject 'config.cpuHotAddEnabled' => 'cpu_hot_add_enabled', 'config.memoryHotAddEnabled' => 'memory_hot_add_enabled', // 'runtime.bootTime' => 'runtime_last_boot_time', - // 'runtime.suspendTime' 'runtime_last_suspend_time', + // 'runtime.suspendTime' 'runtime_last_suspend_time' ]; - /** @var ?HostSystem */ - protected $runtimeHost = null; + protected ?HostSystem $runtimeHost = null; + /** + * @return bool + */ public function hasRuntimeHost(): bool { return $this->get('runtime_host_uuid') !== null; @@ -110,7 +114,8 @@ public function hasRuntimeHost(): bool /** * @return HostSystem - * @throws \Icinga\Exception\NotFoundError + * + * @throws NotFoundError */ public function getRuntimeHost(): HostSystem { @@ -122,11 +127,7 @@ public function getRuntimeHost(): HostSystem $this->runtimeHost = null; } - if ($this->runtimeHost === null) { - $this->runtimeHost = HostSystem::load($uuid, $this->connection); - } - - return $this->runtimeHost; + return $this->runtimeHost ??= HostSystem::load($uuid, $this->connection); } /** @@ -135,18 +136,22 @@ public function getRuntimeHost(): HostSystem * Can be used to avoid duplicate loading of the very same host. As of this * writing, this does NOT change VM properties. * - * @param HostSystem|null $host + * @param ?HostSystem $host + * * @return void + * + * @throws InvalidArgumentException */ - public function setRuntimeHost(?HostSystem $host) + public function setRuntimeHost(?HostSystem $host): void { if ($host === null) { $this->runtimeHost = null; + return; } if ($host->get('uuid') !== $this->get('runtime_host_uuid')) { - throw new \InvalidArgumentException(sprintf( + throw new InvalidArgumentException(sprintf( 'Cannot set runtime host with UUID %s, expected %s', Util::niceUuid($host->get('uuid')), Util::niceUuid($this->get('runtime_host_uuid')) @@ -157,15 +162,14 @@ public function setRuntimeHost(?HostSystem $host) } /** - * @param $value + * @param string|bool|null $value + * * @return $this */ - public function setPaused($value) + public function setPaused(string|bool|null $value): static { // powered off? - if ($value === null) { - $value = 'n'; - } + $value ??= 'n'; if (is_bool($value)) { $value = DbProperty::booleanToDb($value); @@ -206,11 +210,16 @@ public function setPaused($value) * 'netBIOSConfig' => NULL, * 'network' => 'Demo LAN', * }] + * + * @param ?object $value + * + * @return void */ - public function setNet($value) + public function setNet(?object $value): void { if ($value === null || ! isset($value->GuestNicInfo)) { $this->set('guest_ip_addresses', null); + return; } $addresses = []; @@ -221,7 +230,7 @@ public function setNet($value) $addresses[$key] = (object) [ 'connected' => $nic->connected, 'network' => $nic->network, - 'addresses' => [], + 'addresses' => [] ]; } @@ -242,7 +251,7 @@ public function setNet($value) // * tentative Indicates that the uniqueness of the address on the link // is presently being verified // * unknown Indicates that the status cannot be determined - 'state' => property_exists($config, 'state') ? $config->state : null, + 'state' => property_exists($config, 'state') ? $config->state : null ]; } } @@ -251,7 +260,12 @@ public function setNet($value) $this->set('guest_ip_addresses', JsonString::encode((object) $addresses)); } - public function setGuestIpStack($value) + /** + * @param ?object $value + * + * @return void + */ + public function setGuestIpStack(?object $value): void { if ($value === null) { $this->set('guest_ip_stack', null); @@ -316,6 +330,8 @@ public function setGuestIpStack($value) * }] * } * }] + * + * @return ?array */ public function guestIpStack(): ?array { @@ -327,7 +343,10 @@ public function guestIpStack(): ?array return JsonString::decode($value); } - public function guestIpAddresses(): \stdClass + /** + * @return stdClass + */ + public function guestIpAddresses(): stdClass { $value = $this->get('guest_ip_addresses'); if ($value === null) { @@ -338,18 +357,17 @@ public function guestIpAddresses(): \stdClass } /** - * @param $value + * @param ?object $value */ - protected function setBootOptions($value) + protected function setBootOptions(?object $value): void { if ($value === null) { return; } - if (property_exists($value, 'networkBootProtocol')) { - $this->set('boot_network_protocol', $value->networkBootProtocol); - } else { - $this->set('boot_network_protocol', null); - } + $this->set( + 'boot_network_protocol', + property_exists($value, 'networkBootProtocol') ? $value->networkBootProtocol : null + ); // bootOrder might be missing, should then default to disk, net if (property_exists($value, 'bootOrder')) { diff --git a/library/Vspheredb/DbObject/VmDatastoreUsage.php b/library/Vspheredb/DbObject/VmDatastoreUsage.php index df11618c..342450b5 100644 --- a/library/Vspheredb/DbObject/VmDatastoreUsage.php +++ b/library/Vspheredb/DbObject/VmDatastoreUsage.php @@ -6,25 +6,26 @@ class VmDatastoreUsage extends DbObject { - protected $keyName = ['vm_uuid', 'datastore_uuid']; + protected string|array|null $keyName = ['vm_uuid', 'datastore_uuid']; - protected $table = 'vm_datastore_usage'; + protected ?string $table = 'vm_datastore_usage'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'vm_uuid' => null, 'datastore_uuid' => null, 'vcenter_uuid' => null, 'committed' => null, 'uncommitted' => null, 'unshared' => null, - 'ts_updated' => null, + 'ts_updated' => null ]; /** * @param VCenter $vCenter + * * @return static[] */ - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); $objects = static::loadAll( diff --git a/library/Vspheredb/DbObject/VmDisk.php b/library/Vspheredb/DbObject/VmDisk.php index ee325da8..a816ad91 100644 --- a/library/Vspheredb/DbObject/VmDisk.php +++ b/library/Vspheredb/DbObject/VmDisk.php @@ -6,9 +6,9 @@ class VmDisk extends BaseVmHardwareDbObject { - protected $table = 'vm_disk'; + protected ?string $table = 'vm_disk'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'vm_uuid' => null, 'hardware_key' => null, 'disk_uuid' => null, @@ -19,20 +19,20 @@ class VmDisk extends BaseVmHardwareDbObject 'split' => null, 'write_through' => null, 'thin_provisioned' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $objectReferences = [ - 'datastore_uuid', + protected array $objectReferences = [ + 'datastore_uuid' ]; - protected $booleanProperties = [ + protected array $booleanProperties = [ 'split', 'write_through', - 'thin_provisioned', + 'thin_provisioned' ]; - protected $propertyMap = [ + protected array $propertyMap = [ // 'backing.contentId' => 'content_id', // to binary, b82d1a823ecedaeece267061396dac9f 'backing.uuid' => 'disk_uuid', // to binary, 6000C299-5ba6-c2cf-1706-3ba11a5d1df0 'backing.datastore._' => 'datastore_uuid', // make binary unique @@ -46,10 +46,11 @@ class VmDisk extends BaseVmHardwareDbObject ]; /** - * @param $value + * @param ?string $value + * * @return VmDisk */ - public function setDisk_uuid($value) // phpcs:ignore + public function setDisk_uuid(?string $value): VmDisk // phpcs:ignore { if ($value !== null && strlen($value) > 16) { $value = Uuid::fromString($value)->getBytes(); diff --git a/library/Vspheredb/DbObject/VmDiskUsage.php b/library/Vspheredb/DbObject/VmDiskUsage.php index 92c7aaeb..76ef787c 100644 --- a/library/Vspheredb/DbObject/VmDiskUsage.php +++ b/library/Vspheredb/DbObject/VmDiskUsage.php @@ -6,23 +6,24 @@ class VmDiskUsage extends DbObject { - protected $keyName = ['vm_uuid', 'disk_path']; + protected string|array|null $keyName = ['vm_uuid', 'disk_path']; - protected $table = 'vm_disk_usage'; + protected ?string $table = 'vm_disk_usage'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'vm_uuid' => null, 'disk_path' => null, 'capacity' => null, 'free_space' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; /** * @param VCenter $vCenter + * * @return static[] */ - public static function loadAllForVCenter(VCenter $vCenter) + public static function loadAllForVCenter(VCenter $vCenter): array { $dummy = new static(); $objects = static::loadAll( diff --git a/library/Vspheredb/DbObject/VmHardware.php b/library/Vspheredb/DbObject/VmHardware.php index e24e4fdb..dcce8d01 100644 --- a/library/Vspheredb/DbObject/VmHardware.php +++ b/library/Vspheredb/DbObject/VmHardware.php @@ -4,9 +4,9 @@ class VmHardware extends BaseVmHardwareDbObject { - protected $table = 'vm_hardware'; + protected ?string $table = 'vm_hardware'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'vm_uuid' => null, 'hardware_key' => null, 'bus_number' => null, @@ -14,18 +14,18 @@ class VmHardware extends BaseVmHardwareDbObject 'controller_key' => null, 'label' => null, 'summary' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $objectReferences = [ - 'vm_uuid', + protected array $objectReferences = [ + 'vm_uuid' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'deviceInfo.label' => 'label', 'deviceInfo.summary' => 'summary', 'busNumber' => 'bus_number', 'unitNumber' => 'unit_number', - 'controllerKey' => 'controller_key', + 'controllerKey' => 'controller_key' ]; } diff --git a/library/Vspheredb/DbObject/VmNetworkAdapter.php b/library/Vspheredb/DbObject/VmNetworkAdapter.php index bfab1e04..4d96e77e 100644 --- a/library/Vspheredb/DbObject/VmNetworkAdapter.php +++ b/library/Vspheredb/DbObject/VmNetworkAdapter.php @@ -4,26 +4,26 @@ class VmNetworkAdapter extends BaseVmHardwareDbObject { - protected $table = 'vm_network_adapter'; + protected ?string $table = 'vm_network_adapter'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'vm_uuid' => null, 'hardware_key' => null, 'portgroup_uuid' => null, 'port_key' => null, 'mac_address' => null, 'address_type' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $objectReferences = [ - 'portgroup_uuid', + protected array $objectReferences = [ + 'portgroup_uuid' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'backing.port.portgroupKey' => 'portgroup_uuid', 'backing.port.portKey' => 'port_key', 'macAddress' => 'mac_address', // binary(6)? new xxeuid? - 'addressType' => 'address_type', + 'addressType' => 'address_type' ]; } diff --git a/library/Vspheredb/DbObject/VmQuickStats.php b/library/Vspheredb/DbObject/VmQuickStats.php index 165ce8cc..5bb1f9a1 100644 --- a/library/Vspheredb/DbObject/VmQuickStats.php +++ b/library/Vspheredb/DbObject/VmQuickStats.php @@ -6,11 +6,11 @@ class VmQuickStats extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'vm_quick_stats'; + protected ?string $table = 'vm_quick_stats'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'ballooned_memory_mb' => null, 'compressed_memory_kb' => null, @@ -32,10 +32,10 @@ class VmQuickStats extends BaseDbObject 'static_memory_entitlement_mb' => null, 'swapped_memory_mb' => null, 'uptime' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'summary.quickStats.balloonedMemory' => 'ballooned_memory_mb', 'summary.quickStats.compressedMemory' => 'compressed_memory_kb', 'summary.quickStats.consumedOverheadMemory' => 'consumed_overhead_memory_mb', @@ -55,17 +55,26 @@ class VmQuickStats extends BaseDbObject 'summary.quickStats.staticCpuEntitlement' => 'static_cpu_entitlement', 'summary.quickStats.staticMemoryEntitlement' => 'static_memory_entitlement_mb', 'summary.quickStats.swappedMemory' => 'swapped_memory_mb', - 'summary.quickStats.uptimeSeconds' => 'uptime', + 'summary.quickStats.uptimeSeconds' => 'uptime' ]; - protected static $preloadCache = null; + /** @var ?static[] */ + protected static ?array $preloadCache = null; - public static function preloadAll(Db $db) + /** + * @param Db $db + * + * @return void + */ + public static function preloadAll(Db $db): void { self::$preloadCache = self::loadAll($db, null, 'uuid'); } - public static function clearPreloadCache() + /** + * @return void + */ + public static function clearPreloadCache(): void { self::$preloadCache = null; } @@ -73,10 +82,14 @@ public static function clearPreloadCache() /** * Valid are values from 0 to max allowed memory, but I've met -1 on an * ESXi host in the wild (6.7) + * + * @param int $value + * + * @return static */ - public function setHost_memory_usage_mb($value) // phpcs:ignore + public function setHost_memory_usage_mb(int $value): static // phpcs:ignore { - if ((int) $value === -1) { + if ($value === -1) { $value = null; } @@ -85,7 +98,12 @@ public function setHost_memory_usage_mb($value) // phpcs:ignore return $this; } - public static function loadFor(VirtualMachine $object) + /** + * @param VirtualMachine $object + * + * @return VmQuickStats|mixed|static + */ + public static function loadFor(VirtualMachine $object): mixed { if ($object->hasBeenLoadedFromDb()) { $connection = $object->getConnection(); @@ -105,7 +123,12 @@ public static function loadFor(VirtualMachine $object) return static::create(); } - protected function setUptime($value) + /** + * @param int $value + * + * @return VmQuickStats + */ + protected function setUptime(int $value): VmQuickStats { if ($value === 0) { $value = null; diff --git a/library/Vspheredb/DbObject/VmSnapshot.php b/library/Vspheredb/DbObject/VmSnapshot.php index 934263b2..780288c7 100644 --- a/library/Vspheredb/DbObject/VmSnapshot.php +++ b/library/Vspheredb/DbObject/VmSnapshot.php @@ -4,11 +4,11 @@ class VmSnapshot extends BaseDbObject { - protected $keyName = 'uuid'; + protected string|array|null $keyName = 'uuid'; - protected $table = 'vm_snapshot'; + protected ?string $table = 'vm_snapshot'; - protected $defaultProperties = [ + protected ?array $defaultProperties = [ 'uuid' => null, 'parent_uuid' => null, 'vm_uuid' => null, @@ -19,24 +19,24 @@ class VmSnapshot extends BaseDbObject 'ts_create' => null, 'state' => null, 'quiesced' => null, - 'vcenter_uuid' => null, + 'vcenter_uuid' => null ]; - protected $objectReferences = [ + protected array $objectReferences = [ 'vm_uuid', - 'parent_uuid', + 'parent_uuid' ]; - protected $booleanProperties = [ + protected array $booleanProperties = [ 'quiesced', - 'replay_supported', + 'replay_supported' ]; - protected $dateTimeProperties = [ - 'ts_create', + protected array $dateTimeProperties = [ + 'ts_create' ]; - protected $propertyMap = [ + protected array $propertyMap = [ 'id' => 'id', 'name' => 'name', 'description' => 'description', @@ -44,6 +44,6 @@ class VmSnapshot extends BaseDbObject 'quiesced' => 'quiesced', 'createTime' => 'ts_create', 'vm' => 'vm_uuid', - 'parent' => 'parent_uuid', + 'parent' => 'parent_uuid' ]; } diff --git a/library/Vspheredb/EventHistory/VmRecentMigrationHistory.php b/library/Vspheredb/EventHistory/VmRecentMigrationHistory.php index 86a45198..6e634987 100644 --- a/library/Vspheredb/EventHistory/VmRecentMigrationHistory.php +++ b/library/Vspheredb/EventHistory/VmRecentMigrationHistory.php @@ -4,19 +4,26 @@ use Icinga\Module\Vspheredb\Db\DbUtil; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; +use Zend_Db_Adapter_Abstract; class VmRecentMigrationHistory { - protected $vm; + protected VirtualMachine $vm; - protected $db; + protected Zend_Db_Adapter_Abstract $db; + /** + * @param VirtualMachine $vm + */ public function __construct(VirtualMachine $vm) { $this->vm = $vm; $this->db = $vm->getConnection()->getDbAdapter(); } + /** + * @return int + */ public function countWeeklyMigrationAttempts(): int { $query = $this->db->select() diff --git a/library/Vspheredb/Exception/NoPermissionException.php b/library/Vspheredb/Exception/NoPermissionException.php index 581588a2..7843eb44 100644 --- a/library/Vspheredb/Exception/NoPermissionException.php +++ b/library/Vspheredb/Exception/NoPermissionException.php @@ -4,5 +4,5 @@ class NoPermissionException extends VmwareException { - public $paths; + public ?array $paths = null; } diff --git a/library/Vspheredb/Exception/NotAuthenticatedException.php b/library/Vspheredb/Exception/NotAuthenticatedException.php index 9eabd6a4..a862698f 100644 --- a/library/Vspheredb/Exception/NotAuthenticatedException.php +++ b/library/Vspheredb/Exception/NotAuthenticatedException.php @@ -4,5 +4,5 @@ class NotAuthenticatedException extends VmwareException { - public $paths; + public ?array $paths = null; } diff --git a/library/Vspheredb/Exception/VmwareException.php b/library/Vspheredb/Exception/VmwareException.php index 8567e9ab..9cba14c1 100644 --- a/library/Vspheredb/Exception/VmwareException.php +++ b/library/Vspheredb/Exception/VmwareException.php @@ -4,6 +4,7 @@ use Exception; use Icinga\Module\Vspheredb\MappedClass\MissingProperty; +use RuntimeException; class VmwareException extends Exception { @@ -12,11 +13,13 @@ class VmwareException extends Exception /** * @param MissingProperty[] $missingSet + * + * @return VmwareException|RuntimeException */ - public static function forMissingSet($missingSet) + public static function forMissingSet(array $missingSet): VmwareException|RuntimeException { if (empty($missingSet)) { - return new \RuntimeException('Trying to create an Exception for an empty missing set'); + return new RuntimeException('Trying to create an Exception for an empty missing set'); } $paths = []; foreach ($missingSet as $missingProperty) { diff --git a/library/Vspheredb/Format.php b/library/Vspheredb/Format.php index b61987b8..78a42a94 100644 --- a/library/Vspheredb/Format.php +++ b/library/Vspheredb/Format.php @@ -4,7 +4,7 @@ class Format { - public static function bytes($value): string + public static function bytes(float|int $value): string { $base = 1024; $units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; @@ -30,52 +30,45 @@ public static function bytes($value): string return sprintf('%s%s %s', $sign, $output, $units[$pow]); } - public static function mBytes($value): string + public static function mBytes(float|int|null $value): string { return static::bytes($value * 1024 * 1024); } - public static function linkSpeedMb($mb): string + public static function linkSpeedMb(int $mb): string { - if ($mb >= 1000000) { - return sprintf('%.3G TBit/s', $mb / 1000000); - } elseif ($mb >= 1000) { - return sprintf('%.3G GBit/s', $mb / 1000); - } else { - return sprintf('%.3G MBit/s', $mb); - } + return match (true) { + $mb >= 1000000 => sprintf('%.3G TBit/s', $mb / 1000000), + $mb >= 1000 => sprintf('%.3G GBit/s', $mb / 1000), + default => sprintf('%.3G MBit/s', $mb) + }; } - public static function mhz($mhz): string + public static function mhz(?int $mhz): string { if ($mhz === null) { return '-'; } $sign = $mhz < 0 ? '-' : ''; $mhz = abs($mhz); - if ($mhz >= 1000000) { - return $sign . sprintf('%.3G THz', $mhz / 1000000); - } elseif ($mhz >= 1000) { - return $sign . sprintf('%.3G GHz', $mhz / 1000); - } else { - return $sign . sprintf('%.3G MHz', $mhz); - } + + return $sign . match (true) { + $mhz >= 1000000 => sprintf('%.3G THz', $mhz / 1000000), + $mhz >= 1000 => sprintf('%.3G GHz', $mhz / 1000), + default => sprintf('%.3G MHz', $mhz) + }; } public static function mhzWithSeparateUnit($mhz): array { $sign = $mhz < 0 ? '-' : ''; $mhz = abs($mhz); - if ($mhz > 1000000) { - $unit = 'THz'; - $value = $mhz / 1000000; - } elseif ($mhz > 1000) { - $unit = 'GHz'; - $value = $mhz / 1000; - } else { - $unit = 'MHz'; - $value = $mhz; - } + + [$unit, $value] = match (true) { + $mhz >= 1000000 => ['THz', $mhz / 1000000], + $mhz >= 1000 => ['GHz', $mhz / 1000], + default => ['MHz', $mhz] + }; return [$sign . sprintf('%.3G', $value), $unit]; } diff --git a/library/Vspheredb/Hint/ConnectionStateDetails.php b/library/Vspheredb/Hint/ConnectionStateDetails.php index 26532134..bb055a4d 100644 --- a/library/Vspheredb/Hint/ConnectionStateDetails.php +++ b/library/Vspheredb/Hint/ConnectionStateDetails.php @@ -8,16 +8,26 @@ class ConnectionStateDetails { use Translation; - protected static $instance; + protected static ?ConnectionStateDetails $instance = null; - public static function getFor($state) + /** + * @param string $state + * + * @return ?string + */ + public static function getFor(string $state): ?string { return static::instance()->getConnectionStateDetails($state); } - protected function getConnectionStateDetails($state) + /** + * @param string $state + * + * @return ?string + */ + protected function getConnectionStateDetails(string $state): ?string { - $infos = [ + return match ($state) { 'connected' => $this->translate( 'The server has access to the virtual machine' ), @@ -31,27 +41,26 @@ protected function getConnectionStateDetails($state) . ' failures. In this case, no configuration can be returned for' . ' a virtual machine' ), - 'invalid' => $this->translate( + 'invalid' => $this->translate( 'The virtual machine configuration format is invalid. Thus, it is' . ' accessible on disk, but corrupted in a way that does not allow' . ' the server to read the content. In this case, no configuration' . ' can be returned for a virtual machine.' ), - 'orphaned' => $this->translate( + 'orphaned' => $this->translate( 'The virtual machine is no longer registered on the host it is' . ' associated with. For example, a virtual machine that is' . ' unregistered or deleted directly on a host managed by' . ' VirtualCenter shows up in this state.' ), - ]; - - return $infos[$state ?? '']; + default => null + }; } /** - * @return self + * @return static */ - protected static function instance() + protected static function instance(): ConnectionStateDetails { if (static::$instance === null) { static::$instance = new static(); diff --git a/library/Vspheredb/Hook/AnonymizerHook.php b/library/Vspheredb/Hook/AnonymizerHook.php index 5d1fd4a8..7c29874f 100644 --- a/library/Vspheredb/Hook/AnonymizerHook.php +++ b/library/Vspheredb/Hook/AnonymizerHook.php @@ -4,7 +4,17 @@ abstract class AnonymizerHook { + /** + * @param ?string $string + * + * @return ?string + */ abstract public function anonymizeString(?string $string): ?string; + /** + * @param ?string $string + * + * @return ?string + */ abstract public function shuffleString(?string $string): ?string; } diff --git a/library/Vspheredb/Hook/PerfDataConsumerHook.php b/library/Vspheredb/Hook/PerfDataConsumerHook.php index 6d41fc79..53b17ae4 100644 --- a/library/Vspheredb/Hook/PerfDataConsumerHook.php +++ b/library/Vspheredb/Hook/PerfDataConsumerHook.php @@ -4,9 +4,9 @@ use gipfl\InfluxDb\DataPoint; use gipfl\Web\Form; +use Icinga\Application\Hook; use Icinga\Module\Vspheredb\Daemon\RemoteClient; use Icinga\Module\Vspheredb\Storable\PerfdataConsumer; -use Icinga\Web\Hook; use InvalidArgumentException; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; @@ -21,26 +21,41 @@ abstract class PerfDataConsumerHook implements LoggerAwareInterface { use LoggerAwareTrait; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - protected $settings = []; + protected array $settings = []; - protected $queue; + protected array $queue = []; - public static function initialize(LoopInterface $loop, $settings = []) + /** + * @param LoopInterface $loop + * @param array|object $settings + * + * @return $this + */ + public static function initialize(LoopInterface $loop, array|object $settings = []): static { return (new static())->setLoop($loop)->setSettings($settings); } - public function setLoop(LoopInterface $loop) + /** + * @param LoopInterface $loop + * + * @return $this + */ + public function setLoop(LoopInterface $loop): static { $this->loop = $loop; return $this; } - public function setSettings($settings) + /** + * @param array|object $settings + * + * @return $this + */ + public function setSettings(array|object $settings): static { $this->settings = (array) $settings; @@ -49,47 +64,65 @@ public function setSettings($settings) /** * @param string $name + * @param mixed $default + * + * @return mixed */ - public function getSetting(string $name, $default = null) + public function getSetting(string $name, mixed $default = null): mixed { if (array_key_exists($name, $this->settings)) { return $this->settings[$name]; - } else { - return $default; } + + return $default; } /** * @return string */ - public static function getName() + public static function getName(): string { return preg_replace('/Hook$/', '', static::getClassBaseName(get_called_class())); } /** + * @param RemoteClient $client + * * @return Form */ - abstract public function getConfigurationForm(RemoteClient $client); + abstract public function getConfigurationForm(RemoteClient $client): Form; + /** + * @param RemoteClient $client + * + * @return Form + */ public function getSubscriptionForm(RemoteClient $client) { return null; } - public static function createConsumerInstance(PerfdataConsumer $consumer, LoopInterface $loop) + /** + * @param PerfdataConsumer $consumer + * @param LoopInterface $loop + * + * @return static + */ + public static function createConsumerInstance(PerfdataConsumer $consumer, LoopInterface $loop): static { $class = static::getClass($consumer->get('implementation')); - /** @var PerfDataConsumerHook $instance */ + return $class::initialize($loop, $consumer->settings()); } /** * Hint: Currently unused * - * @var DataPoint[] $points + * @param DataPoint[] $points + * + * @return void */ - public function pushDataPoints($points) + public function pushDataPoints(array $points): void { if (empty($this->queue)) { $this->queue[] = $points; @@ -107,34 +140,35 @@ public function pushDataPoints($points) * * @return bool */ - protected function processQueue() + protected function processQueue(): bool { array_pop($this->queue); + return true; } - public static function enum() + /** + * @return array + */ + public static function enum(): array { $enum = []; /** @var static $instance */ foreach (Hook::all('vspheredb/PerfDataConsumer') as $class => $instance) { $module = static::getModuleFromClassName($class); $idx = $instance::getName(); - if ($module === 'vspheredb') { - $enum[$idx] = $idx; - } else { - $enum[$idx] = "$idx ($module)"; - } + $enum[$idx] = $idx . ($module === 'vspheredb' ? '' : " ($module)"); } return $enum; } /** - * @param $name - * @return string|null|static + * @param string $name + * + * @return ?string */ - public static function getClass($name) + public static function getClass(string $name): ?string { // TODO: module/Name for foreign ones? /** @var static $instance */ @@ -147,18 +181,29 @@ public static function getClass($name) return null; } - protected static function getClassBaseName($class) + /** + * @param string $class + * + * @return ?string + */ + protected static function getClassBaseName(string $class): ?string { - $parts = \explode('\\', $class); + $parts = explode('\\', $class); + return array_pop($parts); } - protected static function getModuleFromClassName($class) + /** + * @param string $class + * + * @return string + */ + protected static function getModuleFromClassName(string $class): string { - $parts = \explode('\\', ltrim($class, '\\')); + $parts = explode('\\', ltrim($class, '\\')); if (count($parts) >= 3) { if ($parts[0] === 'Icinga' && $parts[1] === 'Module') { - return \lcfirst($parts[2]); + return lcfirst($parts[2]); } } diff --git a/library/Vspheredb/Ido.php b/library/Vspheredb/Ido.php index 9d0b3bf6..e448f707 100644 --- a/library/Vspheredb/Ido.php +++ b/library/Vspheredb/Ido.php @@ -4,17 +4,17 @@ use Icinga\Data\Db\DbConnection; use Icinga\Data\ResourceFactory; +use Zend_Db_Adapter_Abstract; class Ido { - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected ?Zend_Db_Adapter_Abstract $db = null; protected function __construct() { } - public static function createByResourceName($name) + public static function createByResourceName(string $name): static { $self = new static(); /** @var DbConnection $resource */ @@ -24,66 +24,61 @@ public static function createByResourceName($name) return $self; } - public function isAvailable() + public function isAvailable(): bool { // TODO: check program state return $this->db !== null; } - public function getAllHostStates() + public function getAllHostStates(): ?array { - $query = $this->db->select()->from( - ['o' => 'icinga_objects'], - [ + $query = $this->db->select() + ->from(['o' => 'icinga_objects'], [ 'host_name' => 'o.name1', 'current_state' => "(CASE WHEN has_been_checked = 1 THEN" . " CASE hs.current_state WHEN 0 THEN 'UP' WHEN 1 THEN 'DOWN'" . " WHEN 2 THEN 'UNREACHABLE' END" . " ELSE 'PENDING' END)", 'is_in_downtime' => "(CASE WHEN hs.scheduled_downtime_depth > 0 THEN 'y' ELSE 'n' END)", - 'is_acknowledged' => "(CASE WHEN hs.problem_has_been_acknowledged = 1 THEN 'y' ELSE 'n' END)", - ] - )->join( - ['hs' => 'icinga_hoststatus'], - 'o.object_id = hs.host_object_id', - [] - )->where('o.is_active = 1'); + 'is_acknowledged' => "(CASE WHEN hs.problem_has_been_acknowledged = 1 THEN 'y' ELSE 'n' END)" + ]) + ->join(['hs' => 'icinga_hoststatus'], 'o.object_id = hs.host_object_id', []) + ->where('o.is_active = 1'); return $this->db->fetchAll($query); } - public function hasHost($hostname) + public function hasHost(?string $hostname): bool { if (null === $hostname) { return false; } - return $this->db->fetchOne( - $this->db->select()->from('icinga_objects', [ - 'host_name' => 'name1', - ])->where('name1 = ? AND is_active = 1 AND objecttype_id = 1', $hostname) - ) === $hostname; + return $hostname === $this->db->fetchOne( + $this->db->select() + ->from('icinga_objects', ['host_name' => 'name1']) + ->where('name1 = ? AND is_active = 1 AND objecttype_id = 1', $hostname) + ); } - public function getHostState($hostname) + public function getHostState(string $hostname) { - $query = $this->db->select()->from( - ['o' => 'icinga_objects'], - [ - 'host_name' => 'o.name1', - 'current_state' => "(CASE WHEN has_been_checked = 1 THEN" - . " CASE hs.current_state WHEN 0 THEN 'UP' WHEN 1 THEN 'DOWN'" - . " WHEN 2 THEN 'UNREACHABLE' END" - . " ELSE 'PENDING' END)", - 'is_in_downtime' => "(CASE WHEN hs.scheduled_downtime_depth > 0 THEN 'y' ELSE 'n' END)", - 'is_acknowledged' => "(CASE WHEN hs.problem_has_been_acknowledged = 1 THEN 'y' ELSE 'n' END)", - 'output' => "hs.output", - ] - )->join( - ['hs' => 'icinga_hoststatus'], - 'o.object_id = hs.host_object_id', - [] - )->where('name1 = ? AND is_active = 1 AND objecttype_id = 1', $hostname); + $query = $this->db->select() + ->from( + ['o' => 'icinga_objects'], + [ + 'host_name' => 'o.name1', + 'current_state' => "(CASE WHEN has_been_checked = 1 THEN" + . " CASE hs.current_state WHEN 0 THEN 'UP' WHEN 1 THEN 'DOWN'" + . " WHEN 2 THEN 'UNREACHABLE' END" + . " ELSE 'PENDING' END)", + 'is_in_downtime' => "(CASE WHEN hs.scheduled_downtime_depth > 0 THEN 'y' ELSE 'n' END)", + 'is_acknowledged' => "(CASE WHEN hs.problem_has_been_acknowledged = 1 THEN 'y' ELSE 'n' END)", + 'output' => "hs.output" + ] + ) + ->join(['hs' => 'icinga_hoststatus'], 'o.object_id = hs.host_object_id', []) + ->where('name1 = ? AND is_active = 1 AND objecttype_id = 1', $hostname); return $this->db->fetchRow($query); } diff --git a/library/Vspheredb/MappedClass/AboutInfo.php b/library/Vspheredb/MappedClass/AboutInfo.php index 88e958b4..31f48a67 100644 --- a/library/Vspheredb/MappedClass/AboutInfo.php +++ b/library/Vspheredb/MappedClass/AboutInfo.php @@ -2,13 +2,15 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * AboutInfo * * This data object type describes system information including the name, type, * version, and build number. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class AboutInfo { /** @@ -41,24 +43,24 @@ class AboutInfo /** @var string The complete product name, including the version information. */ public $fullName; - /** @var string|null A globally unique identifier associated with this service instance */ + /** @var ?string A globally unique identifier associated with this service instance */ public $instanceUuid; - /** @var string|null The license product name */ + /** @var ?string The license product name */ public $licenseProductName; - /** @var string|null The license product version */ + /** @var ?string The license product version */ public $licenseProductVersion; /** * Build number for the current session's locale. Typically, this is a small * number reflecting a localization change from the normal product build. * - * @var string|null + * @var ?string */ public $localeBuild; - /** @var string|null Version of the message catalog for the current session's locale */ + /** @var ?string Version of the message catalog for the current session's locale */ public $localeVersion; /** @var string Short form of the product name */ diff --git a/library/Vspheredb/MappedClass/AlarmEvent.php b/library/Vspheredb/MappedClass/AlarmEvent.php index 3782a739..65857997 100644 --- a/library/Vspheredb/MappedClass/AlarmEvent.php +++ b/library/Vspheredb/MappedClass/AlarmEvent.php @@ -4,6 +4,7 @@ use Icinga\Module\Vspheredb\DbObject\VCenter; use Zend_Db_Adapter_Abstract as ZfDbAdapter; +use Zend_Db_Adapter_Exception; abstract class AlarmEvent extends KnownEvent { @@ -19,7 +20,8 @@ public function getDbData(VCenter $vCenter) /** * @param ZfDbAdapter $db * @param VCenter $vCenter - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ public function store(ZfDbAdapter $db, VCenter $vCenter) { @@ -27,9 +29,11 @@ public function store(ZfDbAdapter $db, VCenter $vCenter) // TODO: don't do so if it is old if (isset($this->to) && isset($this->entity)) { - $db->update('object', [ - 'overall_status' => $this->to - ], $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->entity->entity->_))); + $db->update( + 'object', + ['overall_status' => $this->to], + $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->entity->entity->_)) + ); } } diff --git a/library/Vspheredb/MappedClass/AlarmInfo.php b/library/Vspheredb/MappedClass/AlarmInfo.php index da80eb8a..641c3ae6 100644 --- a/library/Vspheredb/MappedClass/AlarmInfo.php +++ b/library/Vspheredb/MappedClass/AlarmInfo.php @@ -16,7 +16,7 @@ class AlarmInfo */ public $alarm; - /** @var int|null The event ID that records the alarm creation */ + /** @var ?int The event ID that records the alarm creation */ public $creationEventId; /** diff --git a/library/Vspheredb/MappedClass/AlarmSpec.php b/library/Vspheredb/MappedClass/AlarmSpec.php index 0b69dcd4..debe9102 100644 --- a/library/Vspheredb/MappedClass/AlarmSpec.php +++ b/library/Vspheredb/MappedClass/AlarmSpec.php @@ -2,10 +2,12 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * Parameters for alarm creation */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class AlarmSpec { /** @var AlarmAction Action to perform when the alarm is triggered */ diff --git a/library/Vspheredb/MappedClass/AlarmState.php b/library/Vspheredb/MappedClass/AlarmState.php index a4a128fc..7967ee76 100644 --- a/library/Vspheredb/MappedClass/AlarmState.php +++ b/library/Vspheredb/MappedClass/AlarmState.php @@ -15,7 +15,7 @@ class AlarmState * Flag to indicate if the alarm's actions have been acknowledged for the * associated ManagedEntity * - * @var bool|null + * @var ?bool */ public $acknowledged; @@ -23,7 +23,7 @@ class AlarmState * The user who acknowledged this triggering. If the triggering has not been * acknowledged, then the value is not valid * - * @var string|null + * @var ?string */ public $acknowledgedByUser; @@ -56,7 +56,7 @@ class AlarmState * * Since vSphere API 6.0 * - * @var int|null + * @var ?int */ public $eventKey; diff --git a/library/Vspheredb/MappedClass/ApiClassMap.php b/library/Vspheredb/MappedClass/ApiClassMap.php index a7bb0270..cb1393d3 100644 --- a/library/Vspheredb/MappedClass/ApiClassMap.php +++ b/library/Vspheredb/MappedClass/ApiClassMap.php @@ -12,11 +12,7 @@ class ApiClassMap public static function getMap() { - if (self::$map === null) { - self::$map = static::prepareMap(); - } - - return self::$map; + return self::$map ??= static::prepareMap(); } /** @@ -41,74 +37,71 @@ public static function requireTypeMap(string $type): string return $map[$type]; } - throw new RuntimeException(sprintf( - 'Type "%s" has no class mapping', - $type - )); + throw new RuntimeException(sprintf('Type "%s" has no class mapping', $type)); } public static function prepareMap() { // Hint: put more specific classes on top, otherwise a more generic one might match - $map = [ + return [ 'RetrieveResult' => RetrieveResult::class, 'RetrievePropertiesResponse' => RetrievePropertiesResponse::class, - 'DynamicData' => DynamicData::class, - 'DynamicProperty' => DynamicProperty::class, - 'ObjectContent' => ObjectContent::class, - 'KeyValue' => KeyValue::class, - 'MissingProperty' => MissingProperty::class, - 'InvalidProperty' => InvalidProperty::class, - 'SystemError' => SystemError::class, - 'NotAuthenticated' => NotAuthenticated::class, - 'NoPermission' => NoPermission::class, - 'SecurityError' => SecurityError::class, - 'LocalizedMethodFault' => LocalizedMethodFault::class, - 'ServiceContent' => ServiceContent::class, - 'AboutInfo' => AboutInfo::class, - 'Folder' => Folder::class, - 'Datacenter' => Datacenter::class, - 'Datastore' => Datastore::class, - 'ResourcePool' => ResourcePool::class, - 'Network' => Network::class, - 'SessionManager' => SessionManager::class, - 'UserSession' => UserSession::class, - 'Tag' => Tag::class, - 'RetrieveOptions' => RetrieveOptions::class, - - 'ObjectSpec' => ObjectSpec::class, - 'SelectionSpec' => SelectionSpec::class, - 'TraversalSpec' => TraversalSpec::class, - 'PropertyFilterSpec' => PropertyFilterSpec::class, - 'PropertySpec' => PropertySpec::class, - 'EventFilterSpec' => EventFilterSpec::class, + 'DynamicData' => DynamicData::class, + 'DynamicProperty' => DynamicProperty::class, + 'ObjectContent' => ObjectContent::class, + 'KeyValue' => KeyValue::class, + 'MissingProperty' => MissingProperty::class, + 'InvalidProperty' => InvalidProperty::class, + 'SystemError' => SystemError::class, + 'NotAuthenticated' => NotAuthenticated::class, + 'NoPermission' => NoPermission::class, + 'SecurityError' => SecurityError::class, + 'LocalizedMethodFault' => LocalizedMethodFault::class, + 'ServiceContent' => ServiceContent::class, + 'AboutInfo' => AboutInfo::class, + 'Folder' => Folder::class, + 'Datacenter' => Datacenter::class, + 'Datastore' => Datastore::class, + 'ResourcePool' => ResourcePool::class, + 'Network' => Network::class, + 'SessionManager' => SessionManager::class, + 'UserSession' => UserSession::class, + 'Tag' => Tag::class, + 'RetrieveOptions' => RetrieveOptions::class, + + 'ObjectSpec' => ObjectSpec::class, + 'SelectionSpec' => SelectionSpec::class, + 'TraversalSpec' => TraversalSpec::class, + 'PropertyFilterSpec' => PropertyFilterSpec::class, + 'PropertySpec' => PropertySpec::class, + 'EventFilterSpec' => EventFilterSpec::class, 'EventFilterSpecByEntity' => EventFilterSpecByEntity::class, 'EventFilterSpecByTime' => EventFilterSpecByTime::class, 'EventFilterSpecByUsername' => EventFilterSpecByUsername::class, - 'ManagedEntity' => ManagedEntity::class, - 'AlarmState' => AlarmState::class, - 'Action' => Action::class, - 'Alarm' => Alarm::class, - 'AlarmAction' => AlarmAction::class, - 'AlarmExpression' => AlarmExpression::class, - 'AlarmInfo' => AlarmInfo::class, - 'AlarmSetting' => AlarmSetting::class, + 'ManagedEntity' => ManagedEntity::class, + 'AlarmState' => AlarmState::class, + 'Action' => Action::class, + 'Alarm' => Alarm::class, + 'AlarmAction' => AlarmAction::class, + 'AlarmExpression' => AlarmExpression::class, + 'AlarmInfo' => AlarmInfo::class, + 'AlarmSetting' => AlarmSetting::class, 'AlarmTriggeringAction' => AlarmTriggeringAction::class, 'AlarmTriggeringActionTransitionSpec' => AlarmTriggeringActionTransitionSpec::class, - 'AndAlarmExpression' => AndAlarmExpression::class, - 'CreateTaskAction' => CreateTaskAction::class, - 'EventAlarmExpression' => EventAlarmExpression::class, - 'EventAlarmExpressionComparison' => EventAlarmExpressionComparison::class, - 'ExtensibleManagedObject' => ExtensibleManagedObject::class, - 'MethodAction' => MethodAction::class, - 'MethodActionArgument' => MethodActionArgument::class, - 'MetricAlarmExpression' => MetricAlarmExpression::class, - 'OrAlarmExpression' => OrAlarmExpression::class, - 'RunScriptAction' => RunScriptAction::class, - 'SendEmailAction' => SendEmailAction::class, - 'SendSNMPAction' => SendSNMPAction::class, - 'StateAlarmExpression' => StateAlarmExpression::class, + 'AndAlarmExpression' => AndAlarmExpression::class, + 'CreateTaskAction' => CreateTaskAction::class, + 'EventAlarmExpression' => EventAlarmExpression::class, + 'EventAlarmExpressionComparison' => EventAlarmExpressionComparison::class, + 'ExtensibleManagedObject' => ExtensibleManagedObject::class, + 'MethodAction' => MethodAction::class, + 'MethodActionArgument' => MethodActionArgument::class, + 'MetricAlarmExpression' => MetricAlarmExpression::class, + 'OrAlarmExpression' => OrAlarmExpression::class, + 'RunScriptAction' => RunScriptAction::class, + 'SendEmailAction' => SendEmailAction::class, + 'SendSNMPAction' => SendSNMPAction::class, + 'StateAlarmExpression' => StateAlarmExpression::class, // 'ManagedObjectNotFoundFault' => "$base\\ManagedObjectNotFoundFault", // 'AlarmEvent' => "$base\\AlarmEvent", @@ -187,37 +180,37 @@ public static function prepareMap() 'DatastoreEventArgument' => DatastoreEventArgument::class, 'HostEventArgument' => HostEventArgument::class, 'VmEventArgument' => VmEventArgument::class, - 'ManagedObjectReference' => ManagedObjectReference::class, - 'NumericRange' => NumericRange::class, - 'ClusterDasFdmHostState' => ClusterDasFdmHostState::class, - 'CustomFieldsManager' => CustomFieldsManager::class, - 'CustomFieldDef' => CustomFieldDef::class, - 'CustomFieldValue' => CustomFieldValue::class, - 'PrivilegePolicyDef' => PrivilegePolicyDef::class, - - 'DistributedVirtualSwitchPortConnection' => DistributedVirtualSwitchPortConnection::class, - 'DistributedVirtualSwitchHostMemberBacking' => DistributedVirtualSwitchHostMemberBacking::class, + 'ManagedObjectReference' => ManagedObjectReference::class, + 'NumericRange' => NumericRange::class, + 'ClusterDasFdmHostState' => ClusterDasFdmHostState::class, + 'CustomFieldsManager' => CustomFieldsManager::class, + 'CustomFieldDef' => CustomFieldDef::class, + 'CustomFieldValue' => CustomFieldValue::class, + 'PrivilegePolicyDef' => PrivilegePolicyDef::class, + + 'DistributedVirtualSwitchPortConnection' => DistributedVirtualSwitchPortConnection::class, + 'DistributedVirtualSwitchHostMemberBacking' => DistributedVirtualSwitchHostMemberBacking::class, 'DistributedVirtualSwitchHostMemberPnicBacking' => DistributedVirtualSwitchHostMemberPnicBacking::class, - 'DistributedVirtualSwitchHostMemberPnicSpec' => DistributedVirtualSwitchHostMemberPnicSpec::class, - 'HostDnsConfig' => HostDnsConfig::class, - 'HostIpConfig' => HostIpConfig::class, - 'HostIpConfigIpV6Address' => HostIpConfigIpV6Address::class, - 'HostIpConfigIpV6AddressConfiguration' => HostIpConfigIpV6AddressConfiguration::class, - 'HostIpRouteConfig' => HostIpRouteConfig::class, - 'HostNetStackInstance' => HostNetStackInstance::class, - 'HostNetworkInfo' => HostNetworkInfo::class, - 'HostOpaqueNetworkInfo' => HostOpaqueNetworkInfo::class, - 'HostOpaqueSwitch' => HostOpaqueSwitch::class, - 'HostPortGroup' => HostPortGroup::class, - 'HostPortGroupPort' => HostPortGroupPort::class, - 'HostPortGroupSpec' => HostPortGroupSpec::class, - 'HostProxySwitch' => HostProxySwitch::class, - 'HostProxySwitchSpec' => HostProxySwitchSpec::class, - 'HostVirtualNic' => HostVirtualNic::class, - 'HostVirtualNicSpec' => HostVirtualNicSpec::class, - 'HostVirtualSwitch' => HostVirtualSwitch::class, - 'HostVirtualSwitchBridge' => HostVirtualSwitchBridge::class, - 'HostVirtualSwitchSpec' => HostVirtualSwitchSpec::class, + 'DistributedVirtualSwitchHostMemberPnicSpec' => DistributedVirtualSwitchHostMemberPnicSpec::class, + 'HostDnsConfig' => HostDnsConfig::class, + 'HostIpConfig' => HostIpConfig::class, + 'HostIpConfigIpV6Address' => HostIpConfigIpV6Address::class, + 'HostIpConfigIpV6AddressConfiguration' => HostIpConfigIpV6AddressConfiguration::class, + 'HostIpRouteConfig' => HostIpRouteConfig::class, + 'HostNetStackInstance' => HostNetStackInstance::class, + 'HostNetworkInfo' => HostNetworkInfo::class, + 'HostOpaqueNetworkInfo' => HostOpaqueNetworkInfo::class, + 'HostOpaqueSwitch' => HostOpaqueSwitch::class, + 'HostPortGroup' => HostPortGroup::class, + 'HostPortGroupPort' => HostPortGroupPort::class, + 'HostPortGroupSpec' => HostPortGroupSpec::class, + 'HostProxySwitch' => HostProxySwitch::class, + 'HostProxySwitchSpec' => HostProxySwitchSpec::class, + 'HostVirtualNic' => HostVirtualNic::class, + 'HostVirtualNicSpec' => HostVirtualNicSpec::class, + 'HostVirtualSwitch' => HostVirtualSwitch::class, + 'HostVirtualSwitchBridge' => HostVirtualSwitchBridge::class, + 'HostVirtualSwitchSpec' => HostVirtualSwitchSpec::class, 'PhysicalNic' => PhysicalNic::class, 'PhysicalNicLinkInfo' => PhysicalNicLinkInfo::class, @@ -237,9 +230,7 @@ public static function prepareMap() 'HostTcpHba' => HostTcpHba::class, 'GuestNicInfo' => GuestNicInfo::class, - 'NetDnsConfigInfo' => NetDnsConfigInfo::class, + 'NetDnsConfigInfo' => NetDnsConfigInfo::class ]; - - return $map; } } diff --git a/library/Vspheredb/MappedClass/ClusterDasFdmHostState.php b/library/Vspheredb/MappedClass/ClusterDasFdmHostState.php index a8d59975..9fee295a 100644 --- a/library/Vspheredb/MappedClass/ClusterDasFdmHostState.php +++ b/library/Vspheredb/MappedClass/ClusterDasFdmHostState.php @@ -2,8 +2,10 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; use gipfl\Json\JsonSerialization; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; +use ReturnTypeWillChange; /** * https://www.vmware.com/support/developer/converter-sdk/conv61_apireference/vim.cluster.DasFdmHostState.html @@ -38,7 +40,7 @@ * restarting VMs as required. All FDMs provide the VM/Application Health * Monitoring Service. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class ClusterDasFdmHostState implements JsonSerialization { /** @@ -96,7 +98,7 @@ class ClusterDasFdmHostState implements JsonSerialization */ public $state; - /** @var ManagedObjectReference|null */ + /** @var ?ManagedObjectReference */ public $stateReporter; public static function fromSerialization($any) @@ -108,12 +110,12 @@ public static function fromSerialization($any) return $self; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function jsonSerialize() { return (object) [ 'state' => $this->state, - 'stateReporter' => $this->stateReporter, + 'stateReporter' => $this->stateReporter ]; } } diff --git a/library/Vspheredb/MappedClass/CustomFieldValue.php b/library/Vspheredb/MappedClass/CustomFieldValue.php index a7fe837f..44ffdc46 100644 --- a/library/Vspheredb/MappedClass/CustomFieldValue.php +++ b/library/Vspheredb/MappedClass/CustomFieldValue.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class CustomFieldValue { /** @var int CustomField ID - references CustomFieldDefs in CustomFieldsManager */ diff --git a/library/Vspheredb/MappedClass/CustomFieldsManager.php b/library/Vspheredb/MappedClass/CustomFieldsManager.php index 4c92ce86..782d36ec 100644 --- a/library/Vspheredb/MappedClass/CustomFieldsManager.php +++ b/library/Vspheredb/MappedClass/CustomFieldsManager.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class CustomFieldsManager { /** @var CustomFieldDef[] */ diff --git a/library/Vspheredb/MappedClass/DatacenterConfigInfo.php b/library/Vspheredb/MappedClass/DatacenterConfigInfo.php index e801d04a..eb1d5bf2 100644 --- a/library/Vspheredb/MappedClass/DatacenterConfigInfo.php +++ b/library/Vspheredb/MappedClass/DatacenterConfigInfo.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class DatacenterConfigInfo { /** diff --git a/library/Vspheredb/MappedClass/DistributedVirtualSwitchHostMemberPnicSpec.php b/library/Vspheredb/MappedClass/DistributedVirtualSwitchHostMemberPnicSpec.php index 5908a6de..1d8c4e53 100644 --- a/library/Vspheredb/MappedClass/DistributedVirtualSwitchHostMemberPnicSpec.php +++ b/library/Vspheredb/MappedClass/DistributedVirtualSwitchHostMemberPnicSpec.php @@ -2,10 +2,12 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * Specification for an individual physical NIC */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class DistributedVirtualSwitchHostMemberPnicSpec { /** diff --git a/library/Vspheredb/MappedClass/DistributedVirtualSwitchPortConnection.php b/library/Vspheredb/MappedClass/DistributedVirtualSwitchPortConnection.php index b9aad901..cf2b1be8 100644 --- a/library/Vspheredb/MappedClass/DistributedVirtualSwitchPortConnection.php +++ b/library/Vspheredb/MappedClass/DistributedVirtualSwitchPortConnection.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * The DistributedVirtualSwitchPortConnection data object represents a connection * or association between a DistributedVirtualPortgroup or a DistributedVirtualPort @@ -11,7 +13,7 @@ * - Host virtual NIC (HostVirtualNic) * - Physical NIC (HostNetworkInfo.pnic) */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class DistributedVirtualSwitchPortConnection { /** diff --git a/library/Vspheredb/MappedClass/DynamicData.php b/library/Vspheredb/MappedClass/DynamicData.php index 503142f1..08c88ac9 100644 --- a/library/Vspheredb/MappedClass/DynamicData.php +++ b/library/Vspheredb/MappedClass/DynamicData.php @@ -2,12 +2,14 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class DynamicData { - /** @var DynamicProperty[]|null */ + /** @var ?DynamicProperty[] */ public $dynamicProperty; - /** @var string|null */ + /** @var ?string */ public $dynamicType; } diff --git a/library/Vspheredb/MappedClass/DynamicProperty.php b/library/Vspheredb/MappedClass/DynamicProperty.php index da3daca9..449e6d25 100644 --- a/library/Vspheredb/MappedClass/DynamicProperty.php +++ b/library/Vspheredb/MappedClass/DynamicProperty.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class DynamicProperty { /** @var string */ diff --git a/library/Vspheredb/MappedClass/ElementDescription.php b/library/Vspheredb/MappedClass/ElementDescription.php index 528f1493..3d0902f6 100644 --- a/library/Vspheredb/MappedClass/ElementDescription.php +++ b/library/Vspheredb/MappedClass/ElementDescription.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class ElementDescription { /** @var string */ diff --git a/library/Vspheredb/MappedClass/EntityEventArgument.php b/library/Vspheredb/MappedClass/EntityEventArgument.php index dcb478a8..8e69017e 100644 --- a/library/Vspheredb/MappedClass/EntityEventArgument.php +++ b/library/Vspheredb/MappedClass/EntityEventArgument.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] abstract class EntityEventArgument { /** @var string */ diff --git a/library/Vspheredb/MappedClass/EventAlarmExpression.php b/library/Vspheredb/MappedClass/EventAlarmExpression.php index f724be4a..661ea7d1 100644 --- a/library/Vspheredb/MappedClass/EventAlarmExpression.php +++ b/library/Vspheredb/MappedClass/EventAlarmExpression.php @@ -32,7 +32,7 @@ class EventAlarmExpression extends AlarmExpression * * Either eventType or eventTypeId must be set. * - * @var string|null + * @var ?string */ public $eventTypeId; diff --git a/library/Vspheredb/MappedClass/EventFilterSpecByTime.php b/library/Vspheredb/MappedClass/EventFilterSpecByTime.php index 23659f84..90742b4d 100644 --- a/library/Vspheredb/MappedClass/EventFilterSpecByTime.php +++ b/library/Vspheredb/MappedClass/EventFilterSpecByTime.php @@ -2,10 +2,12 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * This option specifies a time range used to filter event history */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class EventFilterSpecByTime { /** @@ -27,24 +29,17 @@ class EventFilterSpecByTime /** * @param ?int|string $beginTime * @param ?int|string $endTime + * * @return static */ public static function create($beginTime = null, $endTime = null) { $self = new static(); if ($beginTime) { - if (is_int($beginTime)) { - $self->beginTime = self::makeDateTime($beginTime); - } else { - $self->beginTime = $beginTime; - } + $self->beginTime = is_int($beginTime) ? self::makeDateTime($beginTime) : $beginTime; } if ($endTime) { - if (is_int($endTime)) { - $self->endTime = self::makeDateTime($endTime); - } else { - $self->endTime = $endTime; - } + $self->endTime = is_int($endTime) ? self::makeDateTime($endTime) : $endTime; } return $self; @@ -52,7 +47,9 @@ public static function create($beginTime = null, $endTime = null) /** * DateTime for SOAP call + * * @param $timestamp + * * @return string */ protected static function makeDateTime($timestamp) diff --git a/library/Vspheredb/MappedClass/EventHistoryCollector.php b/library/Vspheredb/MappedClass/EventHistoryCollector.php index 75aec7a2..70118191 100644 --- a/library/Vspheredb/MappedClass/EventHistoryCollector.php +++ b/library/Vspheredb/MappedClass/EventHistoryCollector.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class EventHistoryCollector { /** diff --git a/library/Vspheredb/MappedClass/Fault.php b/library/Vspheredb/MappedClass/Fault.php index c1b36831..df4e8018 100644 --- a/library/Vspheredb/MappedClass/Fault.php +++ b/library/Vspheredb/MappedClass/Fault.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] abstract class Fault { abstract public function getMessage(); diff --git a/library/Vspheredb/MappedClass/GlobalMessageChangedEvent.php b/library/Vspheredb/MappedClass/GlobalMessageChangedEvent.php index 05fd094c..822b6a13 100644 --- a/library/Vspheredb/MappedClass/GlobalMessageChangedEvent.php +++ b/library/Vspheredb/MappedClass/GlobalMessageChangedEvent.php @@ -7,6 +7,6 @@ class GlobalMessageChangedEvent extends SessionEvent /** @var string The new message that was set */ public $message; - /** @var string|null The previous message that was set */ + /** @var ?string The previous message that was set */ public $prevMessage; } diff --git a/library/Vspheredb/MappedClass/HostDnsConfig.php b/library/Vspheredb/MappedClass/HostDnsConfig.php index 3d8e0bfc..5193dd2c 100644 --- a/library/Vspheredb/MappedClass/HostDnsConfig.php +++ b/library/Vspheredb/MappedClass/HostDnsConfig.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * This data object type describes the DNS configuration * @@ -13,7 +15,7 @@ * The address can also consist of the symbol '::' to represent multiple 16-bit * groups of contiguous 0's only once in an address as described in RFC 2373. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostDnsConfig { /** diff --git a/library/Vspheredb/MappedClass/HostIpConfig.php b/library/Vspheredb/MappedClass/HostIpConfig.php index 5b6f12d7..7c7dafc6 100644 --- a/library/Vspheredb/MappedClass/HostIpConfig.php +++ b/library/Vspheredb/MappedClass/HostIpConfig.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostIpConfig { /** diff --git a/library/Vspheredb/MappedClass/HostIpConfigIpV6Address.php b/library/Vspheredb/MappedClass/HostIpConfigIpV6Address.php index 61623842..a086a755 100644 --- a/library/Vspheredb/MappedClass/HostIpConfigIpV6Address.php +++ b/library/Vspheredb/MappedClass/HostIpConfigIpV6Address.php @@ -31,7 +31,7 @@ class HostIpConfigIpV6Address * The ipv6 address. When DHCP is enabled, this property reflects the * current IP configuration and cannot be set * - * @var string|null + * @var ?string */ public $ipAddress; diff --git a/library/Vspheredb/MappedClass/HostIpConfigIpV6AddressConfiguration.php b/library/Vspheredb/MappedClass/HostIpConfigIpV6AddressConfiguration.php index 14f5652a..7dcf37cc 100644 --- a/library/Vspheredb/MappedClass/HostIpConfigIpV6AddressConfiguration.php +++ b/library/Vspheredb/MappedClass/HostIpConfigIpV6AddressConfiguration.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostIpConfigIpV6AddressConfiguration { /** diff --git a/library/Vspheredb/MappedClass/HostIpRouteConfig.php b/library/Vspheredb/MappedClass/HostIpRouteConfig.php index 574745e6..bff36d42 100644 --- a/library/Vspheredb/MappedClass/HostIpRouteConfig.php +++ b/library/Vspheredb/MappedClass/HostIpRouteConfig.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * IP Route Configuration. All IPv4 addresses, subnet addresses, and netmasks * are specified as strings using dotted decimal notation. For example, "192.0.2.1". @@ -11,7 +13,7 @@ * to represent multiple 16-bit groups of contiguous 0's only once in an address * as described in RFC 2373. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostIpRouteConfig { /** diff --git a/library/Vspheredb/MappedClass/HostMultipathInfo.php b/library/Vspheredb/MappedClass/HostMultipathInfo.php index 67b84940..64497379 100644 --- a/library/Vspheredb/MappedClass/HostMultipathInfo.php +++ b/library/Vspheredb/MappedClass/HostMultipathInfo.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * The HostMultipathInfo data object describes the multipathing policy configuration to determine the storage failover * policies for a SCSI logical unit. The multipathing policy configuration operates on SCSI logical units and the paths @@ -15,7 +17,7 @@ * object, only native multipathing exists. That means for these hosts, the MultipathInfo object contains the complete * set of LUNs and paths on the LUNs available on the host. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostMultipathInfo extends DynamicData { /** diff --git a/library/Vspheredb/MappedClass/HostNetStackInstance.php b/library/Vspheredb/MappedClass/HostNetStackInstance.php index e171bdee..94ddc29d 100644 --- a/library/Vspheredb/MappedClass/HostNetStackInstance.php +++ b/library/Vspheredb/MappedClass/HostNetStackInstance.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostNetStackInstance { /** diff --git a/library/Vspheredb/MappedClass/HostNetworkInfo.php b/library/Vspheredb/MappedClass/HostNetworkInfo.php index fbf10e57..40119927 100644 --- a/library/Vspheredb/MappedClass/HostNetworkInfo.php +++ b/library/Vspheredb/MappedClass/HostNetworkInfo.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostNetworkInfo { /** @var boolean */ diff --git a/library/Vspheredb/MappedClass/HostNumericSensorInfo.php b/library/Vspheredb/MappedClass/HostNumericSensorInfo.php index f26eeadd..43ae086a 100644 --- a/library/Vspheredb/MappedClass/HostNumericSensorInfo.php +++ b/library/Vspheredb/MappedClass/HostNumericSensorInfo.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostNumericSensorInfo { /** diff --git a/library/Vspheredb/MappedClass/HostOpaqueNetworkInfo.php b/library/Vspheredb/MappedClass/HostOpaqueNetworkInfo.php index 223eb9b1..c2e62a47 100644 --- a/library/Vspheredb/MappedClass/HostOpaqueNetworkInfo.php +++ b/library/Vspheredb/MappedClass/HostOpaqueNetworkInfo.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostOpaqueNetworkInfo { /** diff --git a/library/Vspheredb/MappedClass/HostOpaqueSwitch.php b/library/Vspheredb/MappedClass/HostOpaqueSwitch.php index b0d09f99..05e8fd72 100644 --- a/library/Vspheredb/MappedClass/HostOpaqueSwitch.php +++ b/library/Vspheredb/MappedClass/HostOpaqueSwitch.php @@ -2,11 +2,13 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * The OpaqueSwitch contains basic information about virtual switches that are * managed by a management plane outside of vSphere. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostOpaqueSwitch { /** diff --git a/library/Vspheredb/MappedClass/HostPortGroup.php b/library/Vspheredb/MappedClass/HostPortGroup.php index df7d86d0..c6b582a8 100644 --- a/library/Vspheredb/MappedClass/HostPortGroup.php +++ b/library/Vspheredb/MappedClass/HostPortGroup.php @@ -2,12 +2,14 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * This data object type is used to describe port groups. Port groups are used * to group virtual network adapters on a virtual switch, associating them with * networks and network policies */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostPortGroup { /** diff --git a/library/Vspheredb/MappedClass/HostPortGroupPort.php b/library/Vspheredb/MappedClass/HostPortGroupPort.php index a1cd099a..88c717af 100644 --- a/library/Vspheredb/MappedClass/HostPortGroupPort.php +++ b/library/Vspheredb/MappedClass/HostPortGroupPort.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * A Port data object type is a runtime representation of network connectivity * between a network service or virtual machine and a virtual switch. This is @@ -9,7 +11,7 @@ * configuration aspects of the network connection. The Port object provides * runtime statistics. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostPortGroupPort { /** @@ -37,7 +39,7 @@ class HostPortGroupPort * - unknown : This port group serves an entity of unspecified kind * - virtualMachine : A virtual machine is connected to this port group * - * @var string|null + * @var ?string */ public $type; } diff --git a/library/Vspheredb/MappedClass/HostPortGroupSpec.php b/library/Vspheredb/MappedClass/HostPortGroupSpec.php index f9a0fcee..c0714b0a 100644 --- a/library/Vspheredb/MappedClass/HostPortGroupSpec.php +++ b/library/Vspheredb/MappedClass/HostPortGroupSpec.php @@ -2,11 +2,13 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * This data object type describes the PortGroup specification representing the * properties on a PortGroup that can be configured */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostPortGroupSpec { /** diff --git a/library/Vspheredb/MappedClass/HostProxySwitch.php b/library/Vspheredb/MappedClass/HostProxySwitch.php index 38775e2a..22ebb6cd 100644 --- a/library/Vspheredb/MappedClass/HostProxySwitch.php +++ b/library/Vspheredb/MappedClass/HostProxySwitch.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * The HostProxySwitch is a software entity which represents the component of a * DistributedVirtualSwitch on a particular host. @@ -10,7 +12,7 @@ * a vSphere distributed switch. The host proxy switch replicates the networking * configuration set on the vSphere distributed switch to the particular host. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostProxySwitch { /** diff --git a/library/Vspheredb/MappedClass/HostProxySwitchSpec.php b/library/Vspheredb/MappedClass/HostProxySwitchSpec.php index 80f66e69..a6069fc1 100644 --- a/library/Vspheredb/MappedClass/HostProxySwitchSpec.php +++ b/library/Vspheredb/MappedClass/HostProxySwitchSpec.php @@ -2,11 +2,13 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * This data object type describes the HostProxySwitch specification representing * the properties on a HostProxySwitch that can be configured once the object exists */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostProxySwitchSpec { /** diff --git a/library/Vspheredb/MappedClass/HostVirtualNic.php b/library/Vspheredb/MappedClass/HostVirtualNic.php index 43e13be6..1255531e 100644 --- a/library/Vspheredb/MappedClass/HostVirtualNic.php +++ b/library/Vspheredb/MappedClass/HostVirtualNic.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostVirtualNic { /** diff --git a/library/Vspheredb/MappedClass/HostVirtualNicSpec.php b/library/Vspheredb/MappedClass/HostVirtualNicSpec.php index 1d2e59a7..a2d648f7 100644 --- a/library/Vspheredb/MappedClass/HostVirtualNicSpec.php +++ b/library/Vspheredb/MappedClass/HostVirtualNicSpec.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class HostVirtualNicSpec { /** diff --git a/library/Vspheredb/MappedClass/HostVirtualSwitch.php b/library/Vspheredb/MappedClass/HostVirtualSwitch.php index 5f11543c..de6a1255 100644 --- a/library/Vspheredb/MappedClass/HostVirtualSwitch.php +++ b/library/Vspheredb/MappedClass/HostVirtualSwitch.php @@ -2,12 +2,14 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * The virtual switch is a software entity to which multiple virtual network * adapters can connect to create a virtual network. It can also be bridged to * a physical network */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostVirtualSwitch { /** diff --git a/library/Vspheredb/MappedClass/HostVirtualSwitchBridge.php b/library/Vspheredb/MappedClass/HostVirtualSwitchBridge.php index 616cb8e2..b9657e52 100644 --- a/library/Vspheredb/MappedClass/HostVirtualSwitchBridge.php +++ b/library/Vspheredb/MappedClass/HostVirtualSwitchBridge.php @@ -2,11 +2,13 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * A bridge connects a virtual switch to a physical network adapter. There are * multiple types of bridges. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostVirtualSwitchBridge extends DynamicData { } diff --git a/library/Vspheredb/MappedClass/HostVirtualSwitchSpec.php b/library/Vspheredb/MappedClass/HostVirtualSwitchSpec.php index 7b616067..90f13f8f 100644 --- a/library/Vspheredb/MappedClass/HostVirtualSwitchSpec.php +++ b/library/Vspheredb/MappedClass/HostVirtualSwitchSpec.php @@ -2,11 +2,13 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * This data object type describes the VirtualSwitch specification representing * the properties on a VirtualSwitch that can be configured once the object exists */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class HostVirtualSwitchSpec { /** diff --git a/library/Vspheredb/MappedClass/KeyValue.php b/library/Vspheredb/MappedClass/KeyValue.php index 6ed821f7..77684bfd 100644 --- a/library/Vspheredb/MappedClass/KeyValue.php +++ b/library/Vspheredb/MappedClass/KeyValue.php @@ -2,10 +2,12 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * Non-localized key/value pair */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class KeyValue { /** diff --git a/library/Vspheredb/MappedClass/KnownEvent.php b/library/Vspheredb/MappedClass/KnownEvent.php index fbb3bd16..699523ec 100644 --- a/library/Vspheredb/MappedClass/KnownEvent.php +++ b/library/Vspheredb/MappedClass/KnownEvent.php @@ -2,10 +2,13 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; use DateTime; use gipfl\Json\JsonSerialization; use Icinga\Module\Vspheredb\DbObject\VCenter; +use ReturnTypeWillChange; use Zend_Db_Adapter_Abstract as ZfDbAdapter; +use Zend_Db_Adapter_Exception; /** * KnownEvent @@ -13,7 +16,7 @@ * We use this as a base class for all vim.event.Event implementations * handled by us */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] abstract class KnownEvent implements JsonSerialization { /** @var int The parent or group ID */ @@ -28,22 +31,22 @@ abstract class KnownEvent implements JsonSerialization /** @var string The user who caused the event */ public $userName; - /** @var string|null A formatted text message describing the event. The message may be localized.*/ + /** @var ?string A formatted text message describing the event. The message may be localized.*/ public $fullFormattedMessage; - /** @var ComputeResourceEventArgument|null */ + /** @var ?ComputeResourceEventArgument */ public $computeResource; - /** @var DatacenterEventArgument|null */ + /** @var ?DatacenterEventArgument */ public $datacenter; /** @var DatastoreEventArgument */ public $ds; - /** @var HostEventArgument|null */ + /** @var ?HostEventArgument */ public $host; - /** @var VmEventArgument|null */ + /** @var ?VmEventArgument */ public $vm; protected $table; @@ -58,7 +61,7 @@ public function getDbData(VCenter $vCenter) 'ts_event_ms' => $this->getTimestampMs(), 'event_type' => array_pop($classParts), 'event_key' => $this->key, - 'event_chain_id' => $this->chainId, + 'event_chain_id' => $this->chainId ]; if (isset($this->fullFormattedMessage) && strlen($this->fullFormattedMessage)) { $data['full_message'] = $this->fullFormattedMessage; @@ -69,17 +72,14 @@ public function getDbData(VCenter $vCenter) public function getTimestampMs() { - if ($this->timestampMs === null) { - $this->timestampMs = $this->timeStringToUnixMs($this->createdTime); - } - - return $this->timestampMs; + return $this->timestampMs ??= $this->timeStringToUnixMs($this->createdTime); } /** * @param ZfDbAdapter $db * @param VCenter $vCenter - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ public function store(ZfDbAdapter $db, VCenter $vCenter) { @@ -106,7 +106,7 @@ public static function fromSerialization($any) return $self; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function jsonSerialize() { // TODO: serialize without (un)serialize(), as this needs to work across nodes diff --git a/library/Vspheredb/MappedClass/LocalizedMethodFault.php b/library/Vspheredb/MappedClass/LocalizedMethodFault.php index 9f122508..7d8f5aa5 100644 --- a/library/Vspheredb/MappedClass/LocalizedMethodFault.php +++ b/library/Vspheredb/MappedClass/LocalizedMethodFault.php @@ -2,12 +2,14 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class LocalizedMethodFault { /** @var MethodFault */ public $fault; - /** @var string|null Servers are required to send the localized message, clients are not */ + /** @var ?string Servers are required to send the localized message, clients are not */ public $localizedMessage; } diff --git a/library/Vspheredb/MappedClass/ManagedEntity.php b/library/Vspheredb/MappedClass/ManagedEntity.php index 8f815de8..c70c821f 100644 --- a/library/Vspheredb/MappedClass/ManagedEntity.php +++ b/library/Vspheredb/MappedClass/ManagedEntity.php @@ -2,9 +2,10 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class ManagedEntity { /** diff --git a/library/Vspheredb/MappedClass/ManagedObjectNotFoundFault.php b/library/Vspheredb/MappedClass/ManagedObjectNotFoundFault.php index 6ad11001..d5ac470f 100644 --- a/library/Vspheredb/MappedClass/ManagedObjectNotFoundFault.php +++ b/library/Vspheredb/MappedClass/ManagedObjectNotFoundFault.php @@ -2,10 +2,12 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * Unused? */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class ManagedObjectNotFoundFault { } diff --git a/library/Vspheredb/MappedClass/MetricAlarmExpression.php b/library/Vspheredb/MappedClass/MetricAlarmExpression.php index 043668e4..63b278a1 100644 --- a/library/Vspheredb/MappedClass/MetricAlarmExpression.php +++ b/library/Vspheredb/MappedClass/MetricAlarmExpression.php @@ -49,7 +49,7 @@ class MetricAlarmExpression extends AlarmExpression * the red status is triggered. If unset, the red status is triggered * immediately when the red condition becomes true. * - * @var int|null + * @var ?int */ public $redInterval; @@ -70,7 +70,7 @@ class MetricAlarmExpression extends AlarmExpression * before the yellow status is triggered. If unset, the yellow status is * triggered immediately when the yellow condition becomes true. * - * @var int|null + * @var ?int */ public $yellowInterval; } diff --git a/library/Vspheredb/MappedClass/MissingProperty.php b/library/Vspheredb/MappedClass/MissingProperty.php index 61a9b068..3148df10 100644 --- a/library/Vspheredb/MappedClass/MissingProperty.php +++ b/library/Vspheredb/MappedClass/MissingProperty.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class MissingProperty { /** @var SytemError|SecurityError These are the known allowed LocalizedMethodFault types */ diff --git a/library/Vspheredb/MappedClass/ObjectContent.php b/library/Vspheredb/MappedClass/ObjectContent.php index d2ff95e9..1d73710e 100644 --- a/library/Vspheredb/MappedClass/ObjectContent.php +++ b/library/Vspheredb/MappedClass/ObjectContent.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Vspheredb\MappedClass; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; +use ReturnTypeWillChange; // https://www.vmware.com/support/developer/converter-sdk/conv61_apireference/vmodl.query.PropertyCollector.ObjectContent.html @@ -17,7 +18,7 @@ class ObjectContent /** * Properties for which values could not be retrieved and the associated fault * - * @var MissingProperty[]|null + * @var ?MissingProperty[] */ public $missingSet; @@ -31,7 +32,7 @@ class ObjectContent /** * Set of name-value pairs for the properties of the managed object * - * @var DynamicProperty[]|null + * @var ?DynamicProperty[] */ public $propSet; @@ -93,7 +94,7 @@ public function toNewObject() return $obj; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function jsonSerialize() { $obj = [ diff --git a/library/Vspheredb/MappedClass/ObjectSpec.php b/library/Vspheredb/MappedClass/ObjectSpec.php index 05b0856a..63b29c13 100644 --- a/library/Vspheredb/MappedClass/ObjectSpec.php +++ b/library/Vspheredb/MappedClass/ObjectSpec.php @@ -49,6 +49,7 @@ class ObjectSpec * @param ManagedObjectReference $obj * @param ?SelectionSpec[] $selectSet * @param ?boolean $skip + * * @return static */ public static function create(ManagedObjectReference $obj, ?array $selectSet = null, $skip = null) diff --git a/library/Vspheredb/MappedClass/PerfCounterInfo.php b/library/Vspheredb/MappedClass/PerfCounterInfo.php index 81278dfd..21f22820 100644 --- a/library/Vspheredb/MappedClass/PerfCounterInfo.php +++ b/library/Vspheredb/MappedClass/PerfCounterInfo.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PerfCounterInfo { /** @var int[] */ diff --git a/library/Vspheredb/MappedClass/PerfEntityMetricCSV.php b/library/Vspheredb/MappedClass/PerfEntityMetricCSV.php index 48710241..36550d3b 100644 --- a/library/Vspheredb/MappedClass/PerfEntityMetricCSV.php +++ b/library/Vspheredb/MappedClass/PerfEntityMetricCSV.php @@ -2,10 +2,12 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; use gipfl\Json\JsonSerialization; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; +use ReturnTypeWillChange; -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class PerfEntityMetricCSV implements JsonSerialization { /** @var ManagedObjectReference */ @@ -29,13 +31,13 @@ public static function fromSerialization($any) return $self; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function jsonSerialize() { return (object) [ 'entity' => $this->entity, 'sampleInfoCSV' => $this->sampleInfoCSV, - 'value' => $this->value, + 'value' => $this->value ]; } } diff --git a/library/Vspheredb/MappedClass/PerfInterval.php b/library/Vspheredb/MappedClass/PerfInterval.php index fad99200..6cee45aa 100644 --- a/library/Vspheredb/MappedClass/PerfInterval.php +++ b/library/Vspheredb/MappedClass/PerfInterval.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PerfInterval { /** @var bool */ diff --git a/library/Vspheredb/MappedClass/PerfMetricId.php b/library/Vspheredb/MappedClass/PerfMetricId.php index 8bdbe345..434b51ac 100644 --- a/library/Vspheredb/MappedClass/PerfMetricId.php +++ b/library/Vspheredb/MappedClass/PerfMetricId.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PerfMetricId { /** @var int */ @@ -30,7 +32,7 @@ class PerfMetricId * - DELTAFILE, for virtual machine snapshot overhead files * - OTHERFILE, for all other files of a virtual machine * - * @var string|null + * @var ?string */ public $instance; diff --git a/library/Vspheredb/MappedClass/PerfMetricSeriesCSV.php b/library/Vspheredb/MappedClass/PerfMetricSeriesCSV.php index 458cf543..9e1e0407 100644 --- a/library/Vspheredb/MappedClass/PerfMetricSeriesCSV.php +++ b/library/Vspheredb/MappedClass/PerfMetricSeriesCSV.php @@ -2,13 +2,15 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; use gipfl\Json\JsonSerialization; +use ReturnTypeWillChange; /** * * https://pubs.vmware.com/vsphere-6-5/topic/com.vmware.wssdk.apiref.doc/vim.PerformanceManager.MetricSeriesCSV.html */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class PerfMetricSeriesCSV implements JsonSerialization { /** @var PerfMetricId */ @@ -26,12 +28,12 @@ public static function fromSerialization($any) return $self; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function jsonSerialize() { return (object) [ 'id' => $this->id, - 'value' => $this->value, + 'value' => $this->value ]; } } diff --git a/library/Vspheredb/MappedClass/PerfQuerySpec.php b/library/Vspheredb/MappedClass/PerfQuerySpec.php index c3fa7e88..0b841aac 100644 --- a/library/Vspheredb/MappedClass/PerfQuerySpec.php +++ b/library/Vspheredb/MappedClass/PerfQuerySpec.php @@ -2,9 +2,10 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; use Icinga\Module\Vspheredb\DbObject\ManagedObject; -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class PerfQuerySpec { /** @var ManagedObject */ @@ -15,7 +16,7 @@ class PerfQuerySpec * to the first available counter. When a startTime is specified, the returned * samples do not include the sample at startTime. * - * @var string|null xsd:dateTime + * @var ?string xsd:dateTime */ public $startTime; @@ -25,7 +26,7 @@ class PerfQuerySpec * metric value. When an endTime is specified, the returned samples include * the sample at endTime. * - * @var string|null xsd:dateTime + * @var ?string xsd:dateTime */ public $endTime; @@ -37,7 +38,7 @@ class PerfQuerySpec * To obtain the greatest detail, use the provider’s refreshRate for this * property. * - * @var int|null + * @var ?int */ public $intervalId; @@ -50,13 +51,13 @@ class PerfQuerySpec * This property is ignored for historical statistics, and is not valid for * the QueryPerfComposite operation. * - * @var int|null + * @var ?int */ public $maxSample; - /** @var string|null enum PerfFormat, 'normal' or 'csv' */ + /** @var ?string enum PerfFormat, 'normal' or 'csv' */ public $format; - /** @var PerfMetricId[]|null */ + /** @var ?PerfMetricId[] */ public $metricId; } diff --git a/library/Vspheredb/MappedClass/PerformanceDescription.php b/library/Vspheredb/MappedClass/PerformanceDescription.php index a24d91c9..50ebb2f5 100644 --- a/library/Vspheredb/MappedClass/PerformanceDescription.php +++ b/library/Vspheredb/MappedClass/PerformanceDescription.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PerformanceDescription { /** @var ElementDescription[] */ diff --git a/library/Vspheredb/MappedClass/PerformanceManager.php b/library/Vspheredb/MappedClass/PerformanceManager.php index f88b514c..18403679 100644 --- a/library/Vspheredb/MappedClass/PerformanceManager.php +++ b/library/Vspheredb/MappedClass/PerformanceManager.php @@ -2,13 +2,15 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PerformanceManager { /** @var PerformanceDescription */ public $description; - /** @var PerfInterval[]|null */ + /** @var ?PerfInterval[] */ public $historicalInterval; /** @var PerfCounterInfo[] */ diff --git a/library/Vspheredb/MappedClass/PhysicalNic.php b/library/Vspheredb/MappedClass/PhysicalNic.php index 494c8668..c4a5f285 100644 --- a/library/Vspheredb/MappedClass/PhysicalNic.php +++ b/library/Vspheredb/MappedClass/PhysicalNic.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PhysicalNic { /** @@ -44,7 +46,7 @@ class PhysicalNic * The current link state of the physical network adapter. If this object * is not set, then the link is down. * - * @var PhysicalNicLinkInfo|null + * @var ?PhysicalNicLinkInfo */ public $linkSpeed; diff --git a/library/Vspheredb/MappedClass/PhysicalNicLinkInfo.php b/library/Vspheredb/MappedClass/PhysicalNicLinkInfo.php index c919bd7d..acc525ec 100644 --- a/library/Vspheredb/MappedClass/PhysicalNicLinkInfo.php +++ b/library/Vspheredb/MappedClass/PhysicalNicLinkInfo.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PhysicalNicLinkInfo { /** diff --git a/library/Vspheredb/MappedClass/PhysicalNicSpec.php b/library/Vspheredb/MappedClass/PhysicalNicSpec.php index 82e76f58..b52aeeff 100644 --- a/library/Vspheredb/MappedClass/PhysicalNicSpec.php +++ b/library/Vspheredb/MappedClass/PhysicalNicSpec.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PhysicalNicSpec { /** diff --git a/library/Vspheredb/MappedClass/PrivilegePolicyDef.php b/library/Vspheredb/MappedClass/PrivilegePolicyDef.php index e8ca1bcc..9a497a6c 100644 --- a/library/Vspheredb/MappedClass/PrivilegePolicyDef.php +++ b/library/Vspheredb/MappedClass/PrivilegePolicyDef.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class PrivilegePolicyDef { /** @var string */ diff --git a/library/Vspheredb/MappedClass/PropertyFilterSpec.php b/library/Vspheredb/MappedClass/PropertyFilterSpec.php index 8f96287f..e8104a34 100644 --- a/library/Vspheredb/MappedClass/PropertyFilterSpec.php +++ b/library/Vspheredb/MappedClass/PropertyFilterSpec.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * Specify the property data that is included in a filter. * @@ -9,7 +11,7 @@ * related managed objects in an inventory hierarchy - for example, to collect * updates from all virtual machines in a given folder. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class PropertyFilterSpec { /** diff --git a/library/Vspheredb/MappedClass/PropertySpec.php b/library/Vspheredb/MappedClass/PropertySpec.php index ec62d44b..82fba486 100644 --- a/library/Vspheredb/MappedClass/PropertySpec.php +++ b/library/Vspheredb/MappedClass/PropertySpec.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * Within a PropertyFilterSpec, A PropertySpec specifies which properties * should be reported to the client for objects of the given managed object @@ -15,7 +17,7 @@ * of a RetrieveResult, where there may be an applicable PropertySpec in more * than one filter. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class PropertySpec { /** diff --git a/library/Vspheredb/MappedClass/RetrieveOptions.php b/library/Vspheredb/MappedClass/RetrieveOptions.php index d730919c..610c4f78 100644 --- a/library/Vspheredb/MappedClass/RetrieveOptions.php +++ b/library/Vspheredb/MappedClass/RetrieveOptions.php @@ -2,7 +2,7 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class RetrieveOptions { /** @@ -26,6 +26,7 @@ class RetrieveOptions /** * @param ?int $maxObjects + * * @return static */ public static function create($maxObjects = null) diff --git a/library/Vspheredb/MappedClass/RetrievePropertiesResponse.php b/library/Vspheredb/MappedClass/RetrievePropertiesResponse.php index 07b71110..4ba915eb 100644 --- a/library/Vspheredb/MappedClass/RetrievePropertiesResponse.php +++ b/library/Vspheredb/MappedClass/RetrievePropertiesResponse.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class RetrievePropertiesResponse { /** @var ObjectContent[] */ diff --git a/library/Vspheredb/MappedClass/RetrieveResult.php b/library/Vspheredb/MappedClass/RetrieveResult.php index 3ee0172e..42074c21 100644 --- a/library/Vspheredb/MappedClass/RetrieveResult.php +++ b/library/Vspheredb/MappedClass/RetrieveResult.php @@ -2,12 +2,15 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; +use ReturnTypeWillChange; + /*** * Result of RetrievePropertiesEx and ContinueRetrievePropertiesEx * * https://www.vmware.com/support/developer/converter-sdk/conv61_apireference/vmodl.query.PropertyCollector.RetrieveResult.html */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class RetrieveResult { /** @var ObjectContent[] retrieved objects */ @@ -28,7 +31,7 @@ class RetrieveResult * _this => PropertyCollector (ref) * token => string * - * @var string|null + * @var ?string */ public $token; @@ -58,7 +61,7 @@ public function makeObjects() return $result; } - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function jsonSerialize() { $result = []; diff --git a/library/Vspheredb/MappedClass/RunScriptAction.php b/library/Vspheredb/MappedClass/RunScriptAction.php index 627062f9..c8919ef1 100644 --- a/library/Vspheredb/MappedClass/RunScriptAction.php +++ b/library/Vspheredb/MappedClass/RunScriptAction.php @@ -2,12 +2,14 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * This data object type specifies a script that is triggered by an alarm. You * can use any elements of the ActionParameter enumerated list as part of your * script to provide information available at runtime. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class RunScriptAction extends Action { /** diff --git a/library/Vspheredb/MappedClass/SecurityError.php b/library/Vspheredb/MappedClass/SecurityError.php index 8952a811..bafa13d1 100644 --- a/library/Vspheredb/MappedClass/SecurityError.php +++ b/library/Vspheredb/MappedClass/SecurityError.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class SecurityError extends LocalizedMethodFault { } diff --git a/library/Vspheredb/MappedClass/SelectionSpec.php b/library/Vspheredb/MappedClass/SelectionSpec.php index 2405d3fc..d1936137 100644 --- a/library/Vspheredb/MappedClass/SelectionSpec.php +++ b/library/Vspheredb/MappedClass/SelectionSpec.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * The SelectionSpec is the base type for data object types that specify what * additional objects to filter. @@ -18,7 +20,7 @@ * * Names are meaningful only within the same FilterSpec. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class SelectionSpec { /** @var ?string Name of the selection specification */ diff --git a/library/Vspheredb/MappedClass/ServiceContent.php b/library/Vspheredb/MappedClass/ServiceContent.php index bc3addf1..4239f5f2 100644 --- a/library/Vspheredb/MappedClass/ServiceContent.php +++ b/library/Vspheredb/MappedClass/ServiceContent.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; /** @@ -16,79 +17,79 @@ * For this reason, use the method RetrieveServiceContent to retrieve the * ServiceContent object. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class ServiceContent { /** @var AboutInfo */ public $about; - /** @var ManagedObjectReference|null to a HostLocalAccountManager */ + /** @var ?ManagedObjectReference to a HostLocalAccountManager */ public $accountManager; - /** @var ManagedObjectReference|null to a AlarmManager */ + /** @var ?ManagedObjectReference to a AlarmManager */ public $alarmManager; - /** @var ManagedObjectReference|null to a AuthorizationManager */ + /** @var ?ManagedObjectReference to a AuthorizationManager */ public $authorizationManager; - /** @var ManagedObjectReference|null to a CertificateManager - since vSphere API 6.0 */ + /** @var ?ManagedObjectReference to a CertificateManager - since vSphere API 6.0 */ public $certificateManager; - /** @var ManagedObjectReference|null to a ClusterProfileManager */ + /** @var ?ManagedObjectReference to a ClusterProfileManager */ public $clusterProfileManager; - /** @var ManagedObjectReference|null to a ProfileComplianceManager */ + /** @var ?ManagedObjectReference to a ProfileComplianceManager */ public $complianceManager; - /** @var ManagedObjectReference|null to a CustomFieldsManager */ + /** @var ?ManagedObjectReference to a CustomFieldsManager */ public $customFieldsManager; - /** @var ManagedObjectReference|null to a CustomizationSpecManager */ + /** @var ?ManagedObjectReference to a CustomizationSpecManager */ public $customizationSpecManager; - /** @var ManagedObjectReference|null to a CustomizationSpecManager */ + /** @var ?ManagedObjectReference to a CustomizationSpecManager */ public $datastoreNamespaceManager; - /** @var ManagedObjectReference|null to a DiagnosticManager */ + /** @var ?ManagedObjectReference to a DiagnosticManager */ public $diagnosticManager; - /** @var ManagedObjectReference|null to a DistributedVirtualSwitchManager */ + /** @var ?ManagedObjectReference to a DistributedVirtualSwitchManager */ public $dvSwitchManager; - /** @var ManagedObjectReference|null to a EventManager */ + /** @var ?ManagedObjectReference to a EventManager */ public $eventManager; - /** @var ManagedObjectReference|null to a ExtensionManager */ + /** @var ?ManagedObjectReference to a ExtensionManager */ public $extensionManager; - /** @var ManagedObjectReference|null to a FileManager */ + /** @var ?ManagedObjectReference to a FileManager */ public $fileManager; - /** @var ManagedObjectReference|null to a GuestOperationsManager */ + /** @var ?ManagedObjectReference to a GuestOperationsManager */ public $guestOperationsManager; - /** @var ManagedObjectReference|null to a HostProfileManager */ + /** @var ?ManagedObjectReference to a HostProfileManager */ public $hostProfileManager; - /** @var ManagedObjectReference|null to a IoFilterManager - since vSphere API 6.0 */ + /** @var ?ManagedObjectReference to a IoFilterManager - since vSphere API 6.0 */ public $ioFilterManager; - /** @var ManagedObjectReference|null to a IpPoolManager */ + /** @var ?ManagedObjectReference to a IpPoolManager */ public $ipPoolManager; - /** @var ManagedObjectReference|null to a LicenseManager */ + /** @var ?ManagedObjectReference to a LicenseManager */ public $licenseManager; - /** @var ManagedObjectReference|null to a LocalizationManager */ + /** @var ?ManagedObjectReference to a LocalizationManager */ public $localizationManager; - /** @var ManagedObjectReference|null to a OverheadMemoryManager - since vSphere API 6.0 */ + /** @var ?ManagedObjectReference to a OverheadMemoryManager - since vSphere API 6.0 */ public $overheadMemoryManager; - /** @var ManagedObjectReference|null to a OvfManager */ + /** @var ?ManagedObjectReference to a OvfManager */ public $ovfManager; - /** @var ManagedObjectReference|null to a PerformanceManager */ + /** @var ?ManagedObjectReference to a PerformanceManager */ public $perfManager; /** @var ManagedObjectReference to a PropertyCollector */ @@ -97,45 +98,45 @@ class ServiceContent /** @var ManagedObjectReference to a Folder */ public $rootFolder; - /** @var ManagedObjectReference|null to a ScheduledTaskManager */ + /** @var ?ManagedObjectReference to a ScheduledTaskManager */ public $scheduledTaskManager; - /** @var ManagedObjectReference|null to a SearchIndex */ + /** @var ?ManagedObjectReference to a SearchIndex */ public $searchIndex; - /** @var ManagedObjectReference|null to a ServiceManager */ + /** @var ?ManagedObjectReference to a ServiceManager */ public $serviceManager; - /** @var ManagedObjectReference|null to a SessionManager */ + /** @var ?ManagedObjectReference to a SessionManager */ public $sessionManager; - /** @var ManagedObjectReference|null to a OptionManager */ + /** @var ?ManagedObjectReference to a OptionManager */ public $setting; - /** @var ManagedObjectReference|null to a HostSnmpSystem */ + /** @var ?ManagedObjectReference to a HostSnmpSystem */ public $snmpSystem; - /** @var ManagedObjectReference|null to a StorageResourceManager */ + /** @var ?ManagedObjectReference to a StorageResourceManager */ public $storageResourceManager; - /** @var ManagedObjectReference|null to a TaskManager */ + /** @var ?ManagedObjectReference to a TaskManager */ public $taskManager; - /** @var ManagedObjectReference|null to a UserDirectory */ + /** @var ?ManagedObjectReference to a UserDirectory */ public $userDirectory; - /** @var ManagedObjectReference|null to a ViewManager */ + /** @var ?ManagedObjectReference to a ViewManager */ public $viewManager; - /** @var ManagedObjectReference|null to a VirtualDiskManager */ + /** @var ?ManagedObjectReference to a VirtualDiskManager */ public $virtualDiskManager; - /** @var ManagedObjectReference|null to a VirtualizationManager */ + /** @var ?ManagedObjectReference to a VirtualizationManager */ public $virtualizationManager; - /** @var ManagedObjectReference|null to a VirtualMachineCompatibilityChecker */ + /** @var ?ManagedObjectReference to a VirtualMachineCompatibilityChecker */ public $vmCompatibilityChecker; - /** @var ManagedObjectReference|null to a VirtualMachineProvisioningChecker */ + /** @var ?ManagedObjectReference to a VirtualMachineProvisioningChecker */ public $vmProvisioningChecker; } diff --git a/library/Vspheredb/MappedClass/SessionManager.php b/library/Vspheredb/MappedClass/SessionManager.php index 7f692324..a50d8ae7 100644 --- a/library/Vspheredb/MappedClass/SessionManager.php +++ b/library/Vspheredb/MappedClass/SessionManager.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * SessionManager * @@ -9,7 +11,7 @@ * clients, determining which clients are currently logged on, and forcing * clients to log off. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class SessionManager { /** @@ -18,7 +20,7 @@ class SessionManager * * RequiredPrivilege: System.Anonymous * - * @var UserSession|null + * @var ?UserSession */ public $currentSession; @@ -45,7 +47,7 @@ class SessionManager * * RequiredPrivilege: System.Anonymous * - * @var array|null + * @var ?array */ public $messageLocaleList; @@ -54,7 +56,7 @@ class SessionManager * * RequiredPrivilege: Sessions.TerminateSession * - * @var UserSession[]|null + * @var ?UserSession[] */ public $sessionList; @@ -67,7 +69,7 @@ class SessionManager * * RequiredPrivilege: System.Anonymous * - * @var array|null + * @var ?array */ public $supportedLocaleList; } diff --git a/library/Vspheredb/MappedClass/Tag.php b/library/Vspheredb/MappedClass/Tag.php index e93dedbc..70f16bf1 100644 --- a/library/Vspheredb/MappedClass/Tag.php +++ b/library/Vspheredb/MappedClass/Tag.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Vspheredb\MappedClass; -#[\AllowDynamicProperties] +use AllowDynamicProperties; + +#[AllowDynamicProperties] class Tag { /** @var string The tag key in human readable form */ diff --git a/library/Vspheredb/MappedClass/TraversalSpec.php b/library/Vspheredb/MappedClass/TraversalSpec.php index 616696e3..c0cdd012 100644 --- a/library/Vspheredb/MappedClass/TraversalSpec.php +++ b/library/Vspheredb/MappedClass/TraversalSpec.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * The TraversalSpec data object type specifies how to derive a new set of * objects to add to the filter. @@ -12,7 +14,7 @@ * * This data object can also be named, using the "name" field in the base type. */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class TraversalSpec extends SelectionSpec { /** @var string Name of the property to use in order to select additional objects */ @@ -33,6 +35,7 @@ class TraversalSpec extends SelectionSpec * @param string $path * @param ?SelectionSpec[] $selectSet * @param ?boolean $skip + * * @return static */ public static function create($name, $type, $path, ?array $selectSet = null, $skip = null) diff --git a/library/Vspheredb/MappedClass/UserSession.php b/library/Vspheredb/MappedClass/UserSession.php index d6499577..d8fb6be4 100644 --- a/library/Vspheredb/MappedClass/UserSession.php +++ b/library/Vspheredb/MappedClass/UserSession.php @@ -2,12 +2,14 @@ namespace Icinga\Module\Vspheredb\MappedClass; +use AllowDynamicProperties; + /** * UserSession * * Information about a current user session */ -#[\AllowDynamicProperties] +#[AllowDynamicProperties] class UserSession { /** @var int (long) Number of API invocations since the session started */ diff --git a/library/Vspheredb/MappedClass/VmEvent.php b/library/Vspheredb/MappedClass/VmEvent.php index 2000cf6d..06b3f643 100644 --- a/library/Vspheredb/MappedClass/VmEvent.php +++ b/library/Vspheredb/MappedClass/VmEvent.php @@ -18,65 +18,37 @@ public function getDbData(VCenter $vCenter) protected function getDatacenterUuid(VCenter $vCenter) { - if ($this->datacenter) { - return $vCenter->makeBinaryGlobalUuid($this->datacenter->datacenter); - } else { - return null; - } + return $this->datacenter ? $vCenter->makeBinaryGlobalUuid($this->datacenter->datacenter) : null; } protected function getDatastoreUuid(VCenter $vCenter) { - if ($this->ds) { - return $vCenter->makeBinaryGlobalUuid($this->ds->datastore); - } else { - return null; - } + return $this->ds ? $vCenter->makeBinaryGlobalUuid($this->ds->datastore) : null; } protected function getComputeResourceUuid(VCenter $vCenter) { - if ($this->computeResource) { - return $vCenter->makeBinaryGlobalUuid($this->computeResource->computeResource); - } else { - return null; - } + return $this->computeResource ? $vCenter->makeBinaryGlobalUuid($this->computeResource->computeResource) : null; } protected function getHostUuid(VCenter $vCenter) { - if ($this->host) { - return $vCenter->makeBinaryGlobalUuid($this->host->host); - } else { - return null; - } + return $this->host ? $vCenter->makeBinaryGlobalUuid($this->host->host) : null; } protected function getVmUuid(VCenter $vCenter) { - if ($this->vm) { - return $vCenter->makeBinaryGlobalUuid($this->vm->vm); - } else { - return null; - } + return $this->vm ? $vCenter->makeBinaryGlobalUuid($this->vm->vm) : null; } protected function getConfigSpec(VCenter $vCenter) { - if (isset($this->configSpec)) { - return \json_encode($this->configSpec); - } else { - return null; - } + return isset($this->configSpec) ? json_encode($this->configSpec) : null; } protected function getConfigChanges(VCenter $vCenter) { - if (isset($this->configChanges)) { - return \json_encode($this->configChanges); - } else { - return null; - } + return isset($this->configChanges) ? json_encode($this->configChanges) : null; } protected function getVmEventDetails(VCenter $vCenter) @@ -90,7 +62,7 @@ protected function getVmEventDetails(VCenter $vCenter) 'vm_uuid' => $this->getVmUuid($vCenter), 'compute_resource_uuid' => $this->getComputeResourceUuid($vCenter), 'config_spec' => $this->getConfigSpec($vCenter), - 'config_changes' => $this->getConfigChanges($vCenter), + 'config_changes' => $this->getConfigChanges($vCenter) ]; } } diff --git a/library/Vspheredb/MappedClass/VmPoweredOffEvent.php b/library/Vspheredb/MappedClass/VmPoweredOffEvent.php index 0a6530db..cd26f270 100644 --- a/library/Vspheredb/MappedClass/VmPoweredOffEvent.php +++ b/library/Vspheredb/MappedClass/VmPoweredOffEvent.php @@ -4,20 +4,24 @@ use Icinga\Module\Vspheredb\DbObject\VCenter; use Zend_Db_Adapter_Abstract as ZfDbAdapter; +use Zend_Db_Adapter_Exception; class VmPoweredOffEvent extends VmEvent { /** * @param ZfDbAdapter $db * @param VCenter $vCenter - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ public function store(ZfDbAdapter $db, VCenter $vCenter) { parent::store($db, $vCenter); - $db->update('virtual_machine', [ - 'runtime_power_state' => 'poweredOff' - ], $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_))); + $db->update( + 'virtual_machine', + ['runtime_power_state' => 'poweredOff'], + $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_)) + ); } } diff --git a/library/Vspheredb/MappedClass/VmPoweredOnEvent.php b/library/Vspheredb/MappedClass/VmPoweredOnEvent.php index 9e080c69..a5556f20 100644 --- a/library/Vspheredb/MappedClass/VmPoweredOnEvent.php +++ b/library/Vspheredb/MappedClass/VmPoweredOnEvent.php @@ -4,20 +4,24 @@ use Icinga\Module\Vspheredb\DbObject\VCenter; use Zend_Db_Adapter_Abstract as ZfDbAdapter; +use Zend_Db_Adapter_Exception; class VmPoweredOnEvent extends VmEvent { /** * @param ZfDbAdapter $db * @param VCenter $vCenter - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ public function store(ZfDbAdapter $db, VCenter $vCenter) { parent::store($db, $vCenter); - $db->update('virtual_machine', [ - 'runtime_power_state' => 'poweredOn' - ], $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_))); + $db->update( + 'virtual_machine', + ['runtime_power_state' => 'poweredOn'], + $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_)) + ); } } diff --git a/library/Vspheredb/MappedClass/VmStartingEvent.php b/library/Vspheredb/MappedClass/VmStartingEvent.php index 52590e15..216f9b76 100644 --- a/library/Vspheredb/MappedClass/VmStartingEvent.php +++ b/library/Vspheredb/MappedClass/VmStartingEvent.php @@ -4,21 +4,25 @@ use Icinga\Module\Vspheredb\DbObject\VCenter; use Zend_Db_Adapter_Abstract as ZfDbAdapter; +use Zend_Db_Adapter_Exception; class VmStartingEvent extends VmEvent { /** * @param ZfDbAdapter $db * @param VCenter $vCenter - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ public function store(ZfDbAdapter $db, VCenter $vCenter) { parent::store($db, $vCenter); // We might see VmStartingEvent but no VmPoweredOffEvent - $db->update('virtual_machine', [ - 'runtime_power_state' => 'poweredOn' - ], $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_))); + $db->update( + 'virtual_machine', + ['runtime_power_state' => 'poweredOn'], + $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_)) + ); } } diff --git a/library/Vspheredb/MappedClass/VmSuspendedEvent.php b/library/Vspheredb/MappedClass/VmSuspendedEvent.php index 57f4f44a..571ddf69 100644 --- a/library/Vspheredb/MappedClass/VmSuspendedEvent.php +++ b/library/Vspheredb/MappedClass/VmSuspendedEvent.php @@ -4,20 +4,24 @@ use Icinga\Module\Vspheredb\DbObject\VCenter; use Zend_Db_Adapter_Abstract as ZfDbAdapter; +use Zend_Db_Adapter_Exception; class VmSuspendedEvent extends VmEvent { /** * @param ZfDbAdapter $db * @param VCenter $vCenter - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ public function store(ZfDbAdapter $db, VCenter $vCenter) { parent::store($db, $vCenter); - $db->update('virtual_machine', [ - 'runtime_power_state' => 'suspended' - ], $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_))); + $db->update( + 'virtual_machine', + ['runtime_power_state' => 'suspended'], + $db->quoteInto('uuid = ?', $vCenter->makeBinaryGlobalUuid($this->vm->vm->_)) + ); } } diff --git a/library/Vspheredb/Monitoring/CheckPlugin.php b/library/Vspheredb/Monitoring/CheckPlugin.php deleted file mode 100644 index 0192e253..00000000 --- a/library/Vspheredb/Monitoring/CheckPlugin.php +++ /dev/null @@ -1,183 +0,0 @@ -loop()->futureTick(function () use ($callable) { - $result = null; - if (\is_callable($callable)) { - try { - $result = $callable(); - } catch (Exception $e) { - $this->addProblem('UNKNOWN', $this->stripNonUtf8Characters($e->getMessage())); - } catch (\Throwable $e) { - $this->addProblem('UNKNOWN', $this->stripNonUtf8Characters($e->getMessage())); - } - } else { - $this->addProblem('UNKNOWN', 'CheckPluginHelper requires a "callable"'); - } - - if ($result instanceof PromiseInterface) { - $result->then(function () { - echo "as\n"; - }, function (Exception $e) { - var_dump('whut'); - $this->addProblem('UNKNOWN', $e->getMessage()); - })->finally(function () { - var_dump('Shut after res'); - $this->shutdown(); - }); - } else { - $this->shutdown(); - } - }); - $this->eventuallyStartMainLoop(); - } - - /** - * @param string $string - * @return string - */ - protected function stripNonUtf8Characters($string) - { - return iconv('UTF-8', 'UTF-8//IGNORE', $string); - } - - /** - * @param null $state - * @return mixed - */ - protected function getStateName($state = null) - { - if ($state === null) { - return $this->stateNameMap[$this->state]; - } else { - return $this->stateNameMap[$this->wantNumericState($state)]; - } - } - - /** - * @param int|string $state - * @param string $message - * - * @return $this - */ - protected function addProblem(int|string $state, string $message): static - { - $this->raiseState($state); - $stateName = $this->getStateName($state); - $this->addMessage(sprintf( - '%s %s', - $this->getOutputScreen()->colorize("[$stateName]", $this->stateColors[$stateName]), - $message - )); - - return $this; - } - - protected function getOutputScreen() - { - if ($this->outputScreen === null) { - $this->outputScreen = Screen::factory(); - } - - return $this->outputScreen; - } - - /** - * @param string $message - * @return $this - */ - protected function addMessage($message) - { - $this->messages[] = $message; - - return $this; - } - - /** - * @param string $message - * @return $this - */ - protected function prependMessage($message) - { - array_unshift($this->messages, $message); - - return $this; - } - - /** - * @param int|string $state - * - * @return $this - */ - protected function raiseState(int|string $state): static - { - $state = $this->wantNumericState($state); - if ($this->sortingStateMap[$state] > $this->sortingStateMap[$this->state]) { - $this->state = $state; - } - - return $this; - } - - /** - * @return int - */ - protected function getState() - { - return $this->state; - } - - /** - * @param int|string $state - * - * @return int - */ - protected function wantNumericState(int|string $state): int - { - if (is_int($state) || ctype_digit($state)) { - if (array_key_exists($state, $this->stateNameMap)) { - return (int) $state; - } else { - throw new InvalidArgumentException(sprintf('%d is not a valid numeric state', $state)); - } - } else { - if (array_key_exists($state, $this->nameStateMap)) { - return $this->nameStateMap[$state]; - } else { - throw new InvalidArgumentException(sprintf('%s is not a valid state name', $state)); - } - } - } - - protected function getMessages() - { - return $this->messages; - } - - protected function shutdown() - { - $messages = $this->getMessages(); - if (! empty($messages)) { - echo implode("\n", $messages) . "\n"; - } - $this->loop()->addTimer(0.01, function () { - $this->loop()->stop(); - exit($this->getState()); - }); - } -} diff --git a/library/Vspheredb/Monitoring/CheckPluginState.php b/library/Vspheredb/Monitoring/CheckPluginState.php deleted file mode 100644 index eb89f121..00000000 --- a/library/Vspheredb/Monitoring/CheckPluginState.php +++ /dev/null @@ -1,160 +0,0 @@ - 0, - self::WARNING => 1, - self::UNKNOWN => 2, - self::CRITICAL => 3 - ]; - - public const NAME_STATE_MAP = [ - self::NAME_OK => self::OK, - self::NAME_WARNING => self::WARNING, - self::NAME_CRITICAL => self::CRITICAL, - self::NAME_UNKNOWN => self::UNKNOWN, - ]; - public const STATE_NAME_MAP = [ - self::OK => self::NAME_OK, - self::WARNING => self::NAME_WARNING, - self::CRITICAL => self::NAME_CRITICAL, - self::UNKNOWN => self::NAME_UNKNOWN, - ]; - - public const STATE_COLORS = [ - self::OK => 'green', - self::WARNING => 'brown', - self::CRITICAL => 'red', - self::UNKNOWN => 'purple', - ]; - - /** @var int */ - protected $state = 0; - - public function __construct($state = self::OK) - { - $this->setState($state); - } - - public function setState($state) - { - $this->state = self::wantNumericState($state); - } - - /** - * @param CheckPluginState|int|string $state - * - * @return void - */ - public function raiseState(CheckPluginState|int|string $state): void - { - if ($state instanceof CheckPluginState) { - $state = $state->getState(); - } else { - $state = self::wantNumericState($state); - } - if (self::SORT_MAP[$state] > self::SORT_MAP[$this->getState()]) { - $this->state = $state; - } - } - - public function isProblem(): bool - { - return $this->getState() !== 0; - } - - public static function compare(CheckPluginState $left, CheckPluginState $right): int - { - $left = self::SORT_MAP[$left->getState()]; - $right = self::SORT_MAP[$right->getState()]; - return $left === $right ? 0 : ($left < $right ? -1 : 1); - } - - public static function getBest(CheckPluginState ...$states): CheckPluginState - { - $formerState = array_shift($states); - if ($formerState === null) { - throw new \RuntimeException('Comparing an empty state list is not possible'); - } - while ($state = array_shift($states)) { - if (self::compare($formerState, $state) === 1) { - $formerState = $state; - } - } - - return $formerState; - } - - public static function getWorst(CheckPluginState ...$states): CheckPluginState - { - $formerState = array_shift($states); - if ($formerState === null) { - throw new \RuntimeException('Comparing an empty state list is not possible'); - } - while ($state = array_shift($states)) { - if (self::compare($formerState, $state) === -1) { - $formerState = $state; - } - } - - return $formerState; - } - - public function getName(): string - { - return self::STATE_NAME_MAP[self::wantNumericState($this->getState())]; - } - - public function getExitCode(): int - { - return $this->state; - } - - public function getColor(): string - { - return self::STATE_COLORS[$this->state]; - } - - protected function getState(): int - { - return $this->state; - } - - /** - * @param string|int $state - * - * @return int - */ - protected static function wantNumericState(string|int $state): int - { - if (is_int($state) || ctype_digit($state)) { - if (array_key_exists($state, self::STATE_NAME_MAP)) { - return (int) $state; - } else { - throw new InvalidArgumentException(sprintf('%d is not a valid numeric state', $state)); - } - } else { - $state = strtoupper($state); - if (array_key_exists($state, self::NAME_STATE_MAP)) { - return self::NAME_STATE_MAP[$state]; - } else { - throw new InvalidArgumentException(sprintf('%s is not a valid state name', $state)); - } - } - } -} diff --git a/library/Vspheredb/Monitoring/CheckResultInterface.php b/library/Vspheredb/Monitoring/CheckResultInterface.php index fe1351c0..b784da6b 100644 --- a/library/Vspheredb/Monitoring/CheckResultInterface.php +++ b/library/Vspheredb/Monitoring/CheckResultInterface.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\Monitoring; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; + interface CheckResultInterface { public function getState(): CheckPluginState; diff --git a/library/Vspheredb/Monitoring/CheckResultSet.php b/library/Vspheredb/Monitoring/CheckResultSet.php index c8305fa4..2646af1e 100644 --- a/library/Vspheredb/Monitoring/CheckResultSet.php +++ b/library/Vspheredb/Monitoring/CheckResultSet.php @@ -2,33 +2,34 @@ namespace Icinga\Module\Vspheredb\Monitoring; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; + class CheckResultSet implements CheckResultInterface { public const NUMERATION_PREFIX = ' \\_ '; - /** @var string */ - protected $name; + protected string $name; /** @var CheckResultInterface[] */ - protected $results = []; + protected array $results = []; - protected $prependedOutput = ''; + protected string $prependedOutput = ''; public function __construct(string $name) { $this->name = $name; } - public function addResult(CheckResultInterface $result) + public function addResult(CheckResultInterface $result): void { $this->results[] = $result; } public function getState(): CheckPluginState { - $state = new CheckPluginState(); + $state = CheckPluginState::OK; foreach ($this->results as $result) { - $state->raiseState($result->getState()); + $state = $state->raise($result->getState()); } return $state; @@ -39,10 +40,10 @@ public function isEmpty(): bool return empty($this->results); } - public function getOutput($prefix = ''): string + public function getOutput(string $prefix = ''): string { $indent = strlen($prefix . self::NUMERATION_PREFIX . '['); - $lines = [sprintf('%s[%s] %s', $prefix, $this->getState()->getName(), $this->name)]; + $lines = [sprintf('%s[%s] %s', $prefix, $this->getState()->name, $this->name)]; if ($this->prependedOutput !== '') { $lines[] = $this->indent($this->prependedOutput, $indent - 4); } @@ -57,7 +58,7 @@ public function getOutput($prefix = ''): string '%s%s[%s] %s', $prefix, self::NUMERATION_PREFIX, - $result->getState()->getName(), + $result->getState()->name, $this->indentAllButFirstLine($result->getOutput(), $indent) ); } @@ -66,7 +67,7 @@ public function getOutput($prefix = ''): string return implode(PHP_EOL, $lines); } - public function prependOutput(string $output) + public function prependOutput(string $output): void { $this->prependedOutput .= $output; } @@ -74,6 +75,7 @@ public function prependOutput(string $output) protected function indentAllButFirstLine(string $string, int $spaces): string { $lines = explode(PHP_EOL, rtrim($string)); + return array_shift($lines) . $this->indent(implode(PHP_EOL, $lines), $spaces); } @@ -83,11 +85,7 @@ protected function indent(string $string, int $spaces): string $output = ''; $prefix = str_repeat(' ', $spaces); foreach ($lines as $line) { - if ($output === '') { - $output .= "$prefix$line"; - } else { - $output .= "\n$prefix$line"; - } + $output .= $output === '' ? "$prefix$line" : "\n$prefix$line"; } return "$output"; // Hint: "$output\n" would be "correcter" diff --git a/library/Vspheredb/Monitoring/CheckRunner.php b/library/Vspheredb/Monitoring/CheckRunner.php index d2805246..c05da24b 100644 --- a/library/Vspheredb/Monitoring/CheckRunner.php +++ b/library/Vspheredb/Monitoring/CheckRunner.php @@ -7,12 +7,11 @@ use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; -use Icinga\Module\Vspheredb\DbObject\Datastore; -use Icinga\Module\Vspheredb\DbObject\HostSystem; -use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\Monitoring\Rule\Definition\ObjectStateRuleSet; use Icinga\Module\Vspheredb\Monitoring\Rule\Definition\RuleSetRegistry; use Icinga\Module\Vspheredb\Monitoring\Rule\Definition\VMwareObjectStateRuleDefinition; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Monitoring\Rule\InheritedSettings; use Icinga\Module\Vspheredb\Monitoring\Rule\MonitoringRulesTree; use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; @@ -22,24 +21,20 @@ class CheckRunner { public const RULESET_NAME_PARAMETER = 'ruleset'; + public const RULE_NAME_PARAMETER = 'rule'; - /** @var Db */ - protected $db; + protected Db $db; - /** @var Screen */ - protected $screen; + protected Screen $screen; - /** @var string */ - protected $ruleSetName; + protected ?string $ruleSetName = null; - /** @var string */ - protected $ruleName; + protected ?string $ruleName = null; - /** @var bool */ - protected $inspect = false; + protected bool $inspect = false; - protected $preloadedTrees = []; + protected array $preloadedTrees = []; public function __construct(Db $db) { @@ -66,22 +61,22 @@ public function enableInspection(bool $inspect = true): void } /** - * @param string $type + * @param ObjectType $type * * @return void */ - public function preloadTreeFor(string $type): void + public function preloadTreeFor(ObjectType $type): void { - $this->preloadedTrees[$type] = new MonitoringRulesTree($this->db, $type); + $this->preloadedTrees[$type->value] = new MonitoringRulesTree($this->db, $type->value); } public function check(BaseDbObject $object): CheckResultSet { - $type = self::getCheckTypeForObject($object); + $type = ObjectType::fromDbObject($object); $registry = $this->getRegistry(); $settings = $this->getSettingsForObject($object, $registry, $type); - $all = new CheckResultSet(sprintf('%s, according configured rules', $this->getTypeLabelForObject($object))); + $all = new CheckResultSet(sprintf('%s, according configured rules', $type->label())); $final = $this->ruleSetName === null ? $all : null; foreach ($registry->getSets() as $set) { if ($settings->isDisabled($set)) { @@ -123,7 +118,7 @@ public function check(BaseDbObject $object): CheckResultSet throw new RuntimeException(sprintf( 'Cannot run checks for Rule "%s", it does not support "%s" objects', $this->ruleName, - $type + $type->value )); } continue; @@ -150,9 +145,7 @@ public function check(BaseDbObject $object): CheckResultSet try { $results = $rule->checkObject($object, $ruleSettings); } catch (Exception $e) { - $results = [ - new SingleCheckResult(new CheckPluginState(CheckPluginState::UNKNOWN), $e->getMessage()) - ]; + $results = [new SingleCheckResult(CheckPluginState::UNKNOWN, $e->getMessage())]; } foreach ($results as $result) { $ruleResult->addResult($result); @@ -168,11 +161,7 @@ public function check(BaseDbObject $object): CheckResultSet protected function getRegistry(): RuleSetRegistry { - if ($this->ruleSetName) { - return RuleSetRegistry::byName($this->ruleSetName); - } else { - return RuleSetRegistry::default(); - } + return $this->ruleSetName ? RuleSetRegistry::byName($this->ruleSetName) : RuleSetRegistry::default(); } /** @@ -181,9 +170,9 @@ protected function getRegistry(): RuleSetRegistry protected function getSettingsForObject( BaseDbObject $object, RuleSetRegistry $registry, - string $type + ObjectType $type ): InheritedSettings { - $tree = $this->preloadedTrees[$type] ?? new MonitoringRulesTree($this->db, $type); + $tree = $this->preloadedTrees[$type->value] ?? new MonitoringRulesTree($this->db, $type->value); $settings = $tree->getInheritedSettingsFor($object); $settings->setInternalDefaults($registry); @@ -192,20 +181,21 @@ protected function getSettingsForObject( /** * @param BaseDbObject $object + * * @return array */ public function checkForDb(BaseDbObject $object): array { - $type = self::getCheckTypeForObject($object); + $type = ObjectType::fromDbObject($object); $registry = $this->getRegistry(); try { $settings = $this->getSettingsForObject($object, $registry, $type); - } catch (NotFoundError $e) { + } catch (NotFoundError) { // Fake Set with just a global state $ruleSetResult = new CheckResultSet((new ObjectStateRuleSet())->getLabel()); $ruleResult = new CheckResultSet((new VMwareObjectStateRuleDefinition())->getLabel()); $ruleResult->addResult(new SingleCheckResult( - new CheckPluginState(CheckPluginState::UNKNOWN), + CheckPluginState::UNKNOWN, 'Could not find the related Managed Object, please check my vCenter permissions' )); $ruleSetResult->addResult($ruleResult); @@ -241,32 +231,6 @@ public function checkForDb(BaseDbObject $object): array return $results; } - protected function getTypeLabelForObject(BaseDbObject $object): string - { - if ($object instanceof HostSystem) { - return 'Host System'; - } elseif ($object instanceof VirtualMachine) { - return 'Virtual Machine'; - } elseif ($object instanceof Datastore) { - return 'Datastore'; - } - - return 'Object'; - } - - public static function getCheckTypeForObject(BaseDbObject $object): string - { - if ($object instanceof HostSystem) { - return 'host'; - } elseif ($object instanceof VirtualMachine) { - return 'vm'; - } elseif ($object instanceof Datastore) { - return 'datastore'; - } - - throw new InvalidArgumentException('Check commands are not supported for ' . get_class($object)); - } - protected function light(string $string): string { return $this->screen->colorize($string, 'lightgray'); diff --git a/library/Vspheredb/Monitoring/Health/ApiConnectionInfo.php b/library/Vspheredb/Monitoring/Health/ApiConnectionInfo.php index e2ee1ce8..73dd9e4e 100644 --- a/library/Vspheredb/Monitoring/Health/ApiConnectionInfo.php +++ b/library/Vspheredb/Monitoring/Health/ApiConnectionInfo.php @@ -6,6 +6,7 @@ use Icinga\Module\Vspheredb\Polling\ApiConnection; use Icinga\Module\Vspheredb\Polling\ServerInfo; use InvalidArgumentException; +use stdClass; class ApiConnectionInfo implements JsonSerialization { @@ -16,22 +17,26 @@ class ApiConnectionInfo implements JsonSerialization ApiConnection::STATE_FAILING => 'CRITICAL', ApiConnection::STATE_STOPPED => 'WARNING', ApiConnection::STATE_STOPPING => 'WARNING', - 'unknown' => 'CRITICAL', + 'unknown' => 'CRITICAL' ]; - /** @var string */ - public $state; - /** @var string */ - public $server; - /** @var int */ - public $serverId; - /** @var int */ - public $vCenterId; - /** @var ?int */ - public $connectionId; - /** @var ?string */ - public $lastErrorMessage = null; + public string $state; + public string $server; + + public int $serverId; + + public int $vCenterId; + + public ?int $connectionId = null; + + public ?string $lastErrorMessage = null; + + /** + * @param ApiConnection $connection + * + * @return ApiConnectionInfo + */ public static function fromConnectionInfo(ApiConnection $connection): ApiConnectionInfo { $server = $connection->getServerInfo(); @@ -47,7 +52,7 @@ public static function fromConnectionInfo(ApiConnection $connection): ApiConnect return $info; } - public static function fromSerialization($any): ApiConnectionInfo + public static function fromSerialization(mixed $any): ApiConnectionInfo { $self = new ApiConnectionInfo( $any->state, @@ -64,6 +69,12 @@ public static function fromSerialization($any): ApiConnectionInfo return $self; } + /** + * @param ServerInfo $server + * @param string $message + * + * @return ApiConnectionInfo + */ public static function failingConnectionForServer(ServerInfo $server, string $message): ApiConnectionInfo { return new ApiConnectionInfo( @@ -75,18 +86,24 @@ public static function failingConnectionForServer(ServerInfo $server, string $me ); } + /** + * @return string + */ public function getIcingaState(): string { return self::STATE_MAP[$this->state]; } - public function jsonSerialize(): \stdClass + /** + * @return stdClass + */ + public function jsonSerialize(): stdClass { $self = (object) [ 'state' => $this->state, 'server' => $this->server, 'serverId' => $this->serverId, - 'vCenterId' => $this->vCenterId, + 'vCenterId' => $this->vCenterId ]; if ($this->lastErrorMessage) { @@ -99,6 +116,15 @@ public function jsonSerialize(): \stdClass return $self; } + /** + * @param string $state + * @param string $server + * @param int $serverId + * @param int $vCenterId + * @param ?string $lastErrorMessage + * + * @throws InvalidArgumentException + */ protected function __construct( string $state, string $server, diff --git a/library/Vspheredb/Monitoring/Health/ServerConnectionInfo.php b/library/Vspheredb/Monitoring/Health/ServerConnectionInfo.php index 6ace3fde..d7083929 100644 --- a/library/Vspheredb/Monitoring/Health/ServerConnectionInfo.php +++ b/library/Vspheredb/Monitoring/Health/ServerConnectionInfo.php @@ -11,15 +11,20 @@ */ class ServerConnectionInfo { - /** @var ?ApiConnectionInfo */ - public $apiConnection = null; - /** @var bool */ - public $enabled; - /** @var string */ - public $serverName; - /** @var bool */ - protected $configured; + public ?ApiConnectionInfo $apiConnection = null; + public bool $enabled; + + public string $serverName; + + protected bool $configured; + + /** + * @param string $serverName + * @param bool $enabled + * @param bool $configured + * @param ?ApiConnectionInfo $apiConnection + */ public function __construct( string $serverName, bool $enabled, @@ -34,12 +39,17 @@ public function __construct( /** * @param ?ApiConnectionInfo $apiConnection + * + * @return void */ public function setApiConnection(?ApiConnectionInfo $apiConnection): void { $this->apiConnection = $apiConnection; } + /** + * @return string + */ public function getState(): string { if ($this->enabled) { @@ -53,6 +63,9 @@ public function getState(): string return 'disabled'; } + /** + * @return string + */ public function getIcingaState(): string { if ($this->enabled) { diff --git a/library/Vspheredb/Monitoring/Health/VCenterInfo.php b/library/Vspheredb/Monitoring/Health/VCenterInfo.php index 75f137d4..839934e1 100644 --- a/library/Vspheredb/Monitoring/Health/VCenterInfo.php +++ b/library/Vspheredb/Monitoring/Health/VCenterInfo.php @@ -7,33 +7,38 @@ use gipfl\ZfDbStore\NotFoundError; use Icinga\Module\Vspheredb\Db\DbUtil; use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; +use Zend_Db_Adapter_Abstract; +use Zend_Db_Select; class VCenterInfo { // Hint: these should become readonly properties - /** @var UuidInterface */ - public $uuid; - /** @var int */ - public $id; - /** @var string */ - public $name; - /** @var string */ - public $software; - /** @var string */ - public $softwareName; - /** @var string */ - public $softwareVersion; - - public static function fromDbRow($row): VCenterInfo + public ?string $uuid = null; + + public ?int $id = null; + + public ?string $name = null; + + public ?string $software = null; + + public ?string $softwareName = null; + + public ?string $softwareVersion = null; + + /** + * @param object $row + * + * @return VCenterInfo + */ + public static function fromDbRow(object $row): VCenterInfo { $self = new static(); $self->id = (int) $row->id; $self->uuid = Uuid::fromBytes(DbUtil::binaryResult($row->uuid))->toString(); - $self->software = \sprintf( + $self->software = sprintf( '%s (%s)', - \preg_replace('/^VMware /', '', $row->software_name), + preg_replace('/^VMware /', '', $row->software_name), $row->software_version ); $self->softwareName = $row->software_name; @@ -44,27 +49,29 @@ public static function fromDbRow($row): VCenterInfo } /** - * @var Adapter|\Zend_Db_Adapter_Abstract $db - * @return Select|\Zend_Db_Select + * @param Zend_Db_Adapter_Abstract|Adapter $db + * + * @return Select|Zend_Db_Select */ - public static function prepareQuery($db) + public static function prepareQuery(Zend_Db_Adapter_Abstract|Adapter $db): Select|Zend_Db_Select { $columns = [ 'uuid' => 'vc.instance_uuid', 'id' => 'vc.id', 'name' => 'vc.name', 'software_name' => 'vc.api_name', - 'software_version' => 'vc.version', + 'software_version' => 'vc.version' ]; return $db->select()->from(['vc' => 'vcenter'], $columns)->order('name'); } /** - * @var Adapter|\Zend_Db_Adapter_Abstract $db + * @param Zend_Db_Adapter_Abstract|Adapter $db + * * @return VCenterInfo[] */ - public static function fetchAll($db): array + public static function fetchAll(Zend_Db_Adapter_Abstract|Adapter $db): array { $result = []; /** @var object{id: int} $row */ @@ -77,11 +84,13 @@ public static function fetchAll($db): array /** * @param int $id + * @param Zend_Db_Adapter_Abstract|Adapter $db + * * @return VCenterInfo + * * @throws NotFoundError - * @var Adapter|\Zend_Db_Adapter_Abstract $db */ - public static function fetchOne(int $id, $db): VCenterInfo + public static function fetchOne(int $id, Zend_Db_Adapter_Abstract|Adapter $db): VCenterInfo { if ($row = $db->fetchRow(static::prepareQuery($db)->where('id = ?', $id))) { return VCenterInfo::fromDbRow($row); diff --git a/library/Vspheredb/Monitoring/MonitoringRuleLookup.php b/library/Vspheredb/Monitoring/MonitoringRuleLookup.php deleted file mode 100644 index 37a1b23e..00000000 --- a/library/Vspheredb/Monitoring/MonitoringRuleLookup.php +++ /dev/null @@ -1,57 +0,0 @@ -db, null, 'uuid'); $datastores = Datastore::loadAll($this->db, null, 'uuid'); $this->presetManagedObjects($datastores, $objects); - $this->checkObjects($datastores, 'datastore'); + $this->checkObjects($datastores, ObjectType::DATASTORE); unset($datastores); HostQuickStats::preloadAll($this->db); $hosts = HostSystem::loadAll($this->db, null, 'uuid'); $this->presetManagedObjects($hosts, $objects); - $this->checkObjects($hosts, 'host'); + $this->checkObjects($hosts, ObjectType::HOST_SYSTEM); VmQuickStats::preloadAll($this->db); // TODO: Preload Disk Usage and Snapshots @@ -70,7 +73,7 @@ public function refresh() $vm->setManagedObject($objects[$uuid]); } } - $this->checkObjects($vms, 'vm'); + $this->checkObjects($vms, ObjectType::VIRTUAL_MACHINE); unset($objects); unset($hosts); @@ -115,10 +118,13 @@ protected function fetchCurrentProblems(): array /** * @param BaseDbObject[] $objects + * @param ObjectType $folderType + * * @return void - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ - protected function checkObjects(array $objects, $folderType) + protected function checkObjects(array $objects, ObjectType $folderType): void { $runner = new CheckRunner($this->db); $runner->preloadTreeFor($folderType); @@ -145,7 +151,7 @@ protected function checkObjects(array $objects, $folderType) } } - protected function rememberCheckedObjects($checked) + protected function rememberCheckedObjects(array $checked): void { foreach ($checked as $uuid => $names) { foreach ($names as $name => $true) { @@ -156,8 +162,10 @@ protected function rememberCheckedObjects($checked) /** * @param array> $results + * * @return array - * @throws \Zend_Db_Adapter_Exception + * + * @throws Zend_Db_Adapter_Exception */ protected function processCheckedObjects(array $results): array { @@ -167,48 +175,48 @@ protected function processCheckedObjects(array $results): array foreach ($results as $uuid => $objectResults) { foreach ($objectResults as $name => $resultSet) { $now = Util::currentTimestamp(); - $state = $resultSet->getState()->getName(); + $state = $resultSet->getState(); $checked[$uuid][$name] = true; if (isset($current[$uuid][$name])) { $formerRow = $current[$uuid][$name]; $formerState = $formerRow->current_state; - if ($formerState === $state) { + if ($formerState === $state->name) { continue; } $where = $db->quoteInto('uuid = ?', DbUtil::quoteBinaryCompat($uuid, $db)) . $db->quoteInto(' AND rule_name = ?', $name); - if ($state === CheckPluginState::NAME_OK) { + if ($state === CheckPluginState::OK) { $db->delete(self::TABLE, $where); } else { $db->update(self::TABLE, [ - 'current_state' => $state, - 'ts_changed_ms' => $now, + 'current_state' => $state->name, + 'ts_changed_ms' => $now ], $where); } $db->insert(self::HISTORY_TABLE, [ 'uuid' => $uuid, - 'current_state' => $state, + 'current_state' => $state->name, 'former_state' => $formerState, 'rule_name' => $name, 'ts_changed_ms' => $now, - 'output' => $resultSet->getOutput(), + 'output' => $resultSet->getOutput() ]); - } elseif ($state !== CheckPluginState::NAME_OK) { + } elseif ($state !== CheckPluginState::OK) { $db->insert(self::TABLE, [ 'uuid' => $uuid, - 'current_state' => $state, + 'current_state' => $state->name, 'rule_name' => $name, 'ts_created_ms' => $now, - 'ts_changed_ms' => $now, + 'ts_changed_ms' => $now ]); // emit new problem $db->insert(self::HISTORY_TABLE, [ 'uuid' => $uuid, - 'current_state' => $state, - 'former_state' => CheckPluginState::NAME_OK, // null? + 'current_state' => $state->name, + 'former_state' => CheckPluginState::OK->name, // null? 'rule_name' => $name, 'ts_changed_ms' => $now, - 'output' => $resultSet->getOutput(), + 'output' => $resultSet->getOutput() ]); } } @@ -217,7 +225,7 @@ protected function processCheckedObjects(array $results): array return $checked; } - protected function dropObsoleteRows() + protected function dropObsoleteRows(): void { $db = $this->db->getDbAdapter(); $db->beginTransaction(); @@ -233,11 +241,11 @@ protected function dropObsoleteRows() $db->delete(self::TABLE, $where); $db->insert(self::HISTORY_TABLE, [ 'uuid' => $uuid, - 'current_state' => CheckPluginState::NAME_OK, + 'current_state' => CheckPluginState::OK->name, 'former_state' => $row->current_state, 'rule_name' => $name, 'ts_changed_ms' => $now, - 'output' => null, + 'output' => null ]); } } @@ -254,7 +262,7 @@ protected function dropObsoleteRows() } } - protected function deleteOutdatedHistoryRows() + protected function deleteOutdatedHistoryRows(): void { $db = $this->db->getDbAdapter(); $expiration = 86400 * 90; diff --git a/library/Vspheredb/Monitoring/Rule/Definition/ActiveMemoryUsageRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/ActiveMemoryUsageRuleDefinition.php index 57b948fc..7c801fb2 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/ActiveMemoryUsageRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/ActiveMemoryUsageRuleDefinition.php @@ -7,9 +7,7 @@ class ActiveMemoryUsageRuleDefinition extends MemoryUsageRuleDefinition { - public const SUPPORTED_OBJECT_TYPES = [ - ObjectType::VIRTUAL_MACHINE, - ]; + public const SUPPORTED_OBJECT_TYPES = [ObjectType::VIRTUAL_MACHINE]; public static function getIdentifier(): string { @@ -21,7 +19,7 @@ public function getLabel(): string return $this->translate('Active Memory Usage'); } - protected function getUsedMemory(BaseDbObject $quickStats) + protected function getUsedMemory(BaseDbObject $quickStats): int { return $quickStats->get('guest_memory_usage_mb') * MemoryUsageHelper::MEGA_BYTE; } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/ComputeResourceUsageRuleSet.php b/library/Vspheredb/Monitoring/Rule/Definition/ComputeResourceUsageRuleSet.php index 48584c02..5d01cf10 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/ComputeResourceUsageRuleSet.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/ComputeResourceUsageRuleSet.php @@ -7,7 +7,7 @@ class ComputeResourceUsageRuleSet extends MonitoringRuleSetDefinition public const RULE_CLASSES = [ CpuUsageRuleDefinition::class, MemoryUsageRuleDefinition::class, - ActiveMemoryUsageRuleDefinition::class, + ActiveMemoryUsageRuleDefinition::class ]; public function getLabel(): string diff --git a/library/Vspheredb/Monitoring/Rule/Definition/ConfigurationPolicyRuleSet.php b/library/Vspheredb/Monitoring/Rule/Definition/ConfigurationPolicyRuleSet.php index b5df1410..5e1d68b8 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/ConfigurationPolicyRuleSet.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/ConfigurationPolicyRuleSet.php @@ -4,9 +4,7 @@ class ConfigurationPolicyRuleSet extends MonitoringRuleSetDefinition { - public const RULE_CLASSES = [ - GuestUtilitiesRuleDefinition::class, - ]; + public const RULE_CLASSES = [GuestUtilitiesRuleDefinition::class]; public function getLabel(): string { diff --git a/library/Vspheredb/Monitoring/Rule/Definition/CpuUsageRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/CpuUsageRuleDefinition.php index d0adbe54..c8f875c7 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/CpuUsageRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/CpuUsageRuleDefinition.php @@ -9,7 +9,7 @@ use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\DbObject\VmQuickStats; use Icinga\Module\Vspheredb\Format; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; use Icinga\Module\Vspheredb\Monitoring\SingleCheckResult; @@ -18,7 +18,7 @@ class CpuUsageRuleDefinition extends MonitoringRuleDefinition { public const SUPPORTED_OBJECT_TYPES = [ ObjectType::HOST_SYSTEM, - ObjectType::VIRTUAL_MACHINE, + ObjectType::VIRTUAL_MACHINE ]; public static function getIdentifier(): string @@ -58,12 +58,12 @@ public function checkObject(BaseDbObject $object, Settings $settings): array $mhzSingleCpu = 2000; } } - $state = new CheckPluginState(); + $state = CheckPluginState::OK; $mhzUsed = $quickStats->get('overall_cpu_usage'); $mhzCapacity = $mhzSingleCpu * $cpuCount; $mhzFree = $mhzCapacity - $mhzUsed; if ($mhzCapacity === 0) { - $state->raiseState(CheckPluginState::UNKNOWN); + $state = $state->raise(CheckPluginState::UNKNOWN); return [ new SingleCheckResult($state, sprintf( '%s used, but got ZERO capacity (%d CPUs, %s per CPU)', @@ -86,11 +86,11 @@ public function checkObject(BaseDbObject $object, Settings $settings): array $min = $settings->get('warning_if_less_than_percent_free'); if ($min && ($percentFree < (float) $min)) { - $state->raiseState(CheckPluginState::WARNING); + $state = $state->raise(CheckPluginState::WARNING); } $min = $settings->get('critical_if_less_than_percent_free'); if ($min && ($percentFree < (float) $min)) { - $state->raiseState(CheckPluginState::CRITICAL); + $state = $state->raise(CheckPluginState::CRITICAL); } return [ @@ -103,12 +103,12 @@ public function getParameters(): array return [ 'warning_if_less_than_percent_free' => ['number', [ 'label' => $this->translate('Raise Warning with less than X percent free'), - 'placeholder' => '30', + 'placeholder' => '30' ]], 'critical_if_less_than_percent_free' => ['number', [ 'label' => $this->translate('Raise Critical with less than X percent free'), - 'placeholder' => '10', - ]], + 'placeholder' => '10' + ]] ]; } } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/DatastoreHealthRuleSet.php b/library/Vspheredb/Monitoring/Rule/Definition/DatastoreHealthRuleSet.php index f0bd146e..0354acc8 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/DatastoreHealthRuleSet.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/DatastoreHealthRuleSet.php @@ -4,9 +4,7 @@ class DatastoreHealthRuleSet extends MonitoringRuleSetDefinition { - public const RULE_CLASSES = [ - DatastoreUsageRuleDefinition::class, - ]; + public const RULE_CLASSES = [DatastoreUsageRuleDefinition::class]; public function getLabel(): string { diff --git a/library/Vspheredb/Monitoring/Rule/Definition/DatastoreUsageRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/DatastoreUsageRuleDefinition.php index 39d2b331..cde16d9e 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/DatastoreUsageRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/DatastoreUsageRuleDefinition.php @@ -8,9 +8,7 @@ class DatastoreUsageRuleDefinition extends MonitoringRuleDefinition { - public const SUPPORTED_OBJECT_TYPES = [ - ObjectType::DATASTORE, - ]; + public const SUPPORTED_OBJECT_TYPES = [ObjectType::DATASTORE]; public static function getIdentifier(): string { diff --git a/library/Vspheredb/Monitoring/Rule/Definition/DiskHealthRuleSet.php b/library/Vspheredb/Monitoring/Rule/Definition/DiskHealthRuleSet.php index 6cc66e9a..28e0fee1 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/DiskHealthRuleSet.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/DiskHealthRuleSet.php @@ -6,7 +6,7 @@ class DiskHealthRuleSet extends MonitoringRuleSetDefinition { public const RULE_CLASSES = [ SnapshotsRuleDefinition::class, - DiskUsageRuleDefinition::class, + DiskUsageRuleDefinition::class ]; public function getLabel(): string diff --git a/library/Vspheredb/Monitoring/Rule/Definition/DiskUsageRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/DiskUsageRuleDefinition.php index 77e9ad22..87f0dc57 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/DiskUsageRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/DiskUsageRuleDefinition.php @@ -9,9 +9,7 @@ class DiskUsageRuleDefinition extends MonitoringRuleDefinition { - public const SUPPORTED_OBJECT_TYPES = [ - ObjectType::VIRTUAL_MACHINE, - ]; + public const SUPPORTED_OBJECT_TYPES = [ObjectType::VIRTUAL_MACHINE]; public static function getIdentifier(): string { @@ -65,7 +63,7 @@ protected function filterMatchesPath(string $filterString, string $path): bool protected static function stringMatches(string $filterString, string $string): bool { - if (strpos($filterString, '*') === false) { + if (! str_contains($filterString, '*')) { return $string === $filterString; } @@ -85,7 +83,7 @@ public function checkObject(BaseDbObject $object, Settings $settings): array $disks = $db->fetchAll($db->select()->from('vm_disk_usage', [ 'disk_path', 'capacity', - 'free_space', + 'free_space' ])->where('vm_disk_usage.vm_uuid = ?', $object->getConnection()->quoteBinary($object->get('uuid')))); $instanceSettings = []; @@ -114,12 +112,12 @@ public function getParameters(): array return [ 'disk_path_filter' => ['text', [ 'label' => $this->translate('Apply to specific disks only'), - 'placeholder' => 'e.g. C:\\, /var/*, C:\\|D:\\|E:\\', + 'placeholder' => 'e.g. C:\\, /var/*, C:\\|D:\\|E:\\' ]], 'disk_path_ignore' => ['text', [ 'label' => $this->translate('Ignore specific disks'), - 'placeholder' => 'e.g. C:\\, */volume-subpaths/*|/var/lib/kubelet/*', - ]], + 'placeholder' => 'e.g. C:\\, */volume-subpaths/*|/var/lib/kubelet/*' + ]] ] + MemoryUsageHelper::getParameters(); } } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/GuestUtilitiesRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/GuestUtilitiesRuleDefinition.php index 32a06b5d..bce66a1b 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/GuestUtilitiesRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/GuestUtilitiesRuleDefinition.php @@ -4,7 +4,7 @@ use gipfl\IcingaWeb2\Link; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState as State; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState as State; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\MonitoringStateTrigger as Trigger; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; @@ -16,9 +16,7 @@ class GuestUtilitiesRuleDefinition extends MonitoringRuleDefinition { - public const SUPPORTED_OBJECT_TYPES = [ - ObjectType::VIRTUAL_MACHINE, - ]; + public const SUPPORTED_OBJECT_TYPES = [ObjectType::VIRTUAL_MACHINE]; public static function getIdentifier(): string { @@ -33,26 +31,26 @@ public function getLabel(): string public function getSuggestedSettings(): array { return [ - 'on_vcenter_complaint' => Trigger::RAISE_WARNING, - 'on_not_installed' => Trigger::RAISE_WARNING, - 'on_not_running' => Trigger::RAISE_WARNING, - 'version_2147483647' => Trigger::IGNORE, + 'on_vcenter_complaint' => Trigger::RAISE_WARNING->value, + 'on_not_installed' => Trigger::RAISE_WARNING->value, + 'on_not_running' => Trigger::RAISE_WARNING->value, + 'version_2147483647' => Trigger::IGNORE->value ]; } public function checkObject(BaseDbObject $object, Settings $settings): array { - $state = new State(); + $state = State::OK; $version = $object->get('guest_tools_version'); $versionInfo = ''; if ($version === '2147483647') { $versionInfo = "v$version"; - $state->raiseState(Trigger::getMonitoringState($settings->get('version_2147483647'))); + $state = $state->raise(Trigger::nullableFrom($settings->get('version_2147483647'))->monitoringState()); } elseif ( $version !== null && ( - preg_match('/^([89])(\d{1})(\d{2})$/', $version, $m) - || preg_match('/^(1\d)(\d{1})(\d{2})$/', $version, $m) + preg_match('/^([89])(\d{1})(\d{2})$/', $version, $m) + || preg_match('/^(1\d)(\d{1})(\d{2})$/', $version, $m) ) ) { $version = sprintf('%d.%d.%d', $m[1], $m[2], $m[3]); @@ -60,27 +58,28 @@ public function checkObject(BaseDbObject $object, Settings $settings): array $required = $settings->get('warning_if_less_than'); if ($required && version_compare($version, $required) < 0) { $versionInfo .= ", less than $required"; - $state->raiseState(State::WARNING); + $state = $state->raise(State::WARNING); } $required = $settings->get('critical_if_less_than'); if ($required && version_compare($version, $required) < 0) { $versionInfo .= ", less than $required"; - $state->raiseState(State::CRITICAL); + $state = $state->raise(State::CRITICAL); } } switch ($object->get('guest_tools_status')) { case 'toolsNotInstalled': $message = 'Guest Tools are NOT installed'; - $state->raiseState(Trigger::getMonitoringState($settings->get('on_not_installed'))); + $state = $state->raise(Trigger::nullableFrom($settings->get('on_not_installed'))->monitoringState()); break; case 'toolsNotRunning': $message = sprintf('Guest Tools (%s) are NOT running', $versionInfo); - $state->raiseState(Trigger::getMonitoringState($settings->get('on_not_running'))); + $state = $state->raise(Trigger::nullableFrom($settings->get('on_not_running'))->monitoringState()); break; case 'toolsOld': $message = sprintf('Guest Tools (%s) are old (considered outdated by VMware)', $versionInfo); - $state->raiseState(Trigger::getMonitoringState($settings->get('on_vcenter_complaint'))); + $state = $state->raise(Trigger::nullableFrom($settings->get('on_vcenter_complaint')) + ->monitoringState()); break; case 'toolsOk': $message = sprintf('Guest Tools (%s) are up to date and running', $versionInfo); @@ -90,29 +89,27 @@ public function checkObject(BaseDbObject $object, Settings $settings): array $message = 'Guest Tools status is now known'; } - return [ - new SingleCheckResult($state, $message) - ]; + return [new SingleCheckResult($state, $message)]; } public function getParameters(): array { return [ 'on_vcenter_complaint' => ['state_trigger', [ - 'label' => $this->translate('When the vCenter says "outdated"'), + 'label' => $this->translate('When the vCenter says "outdated"') ]], 'on_not_installed' => ['state_trigger', [ - 'label' => $this->translate('When not installed'), + 'label' => $this->translate('When not installed') ]], 'on_not_running' => ['state_trigger', [ - 'label' => $this->translate('When installed, but not running'), + 'label' => $this->translate('When installed, but not running') ]], 'version_2147483647' => ['state_trigger', [ 'label' => $this->translate('On version 2147483647'), 'description' => Html::sprintf( $this->translate('Please read %s'), Link::create('KB 51988', 'https://kb.vmware.com/s/article/51988') - ), + ) ]], 'warning_if_less_than' => ['text', [ 'label' => $this->translate('Raise Warning for versions lower than'), @@ -121,7 +118,7 @@ public function getParameters(): array 'critical_if_less_than' => ['text', [ 'label' => $this->translate('Raise Critical for versions lower than'), 'placeholder' => '00.0.00' - ]], + ]] ]; } } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageHelper.php b/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageHelper.php index 8a35131a..7dbafcbd 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageHelper.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageHelper.php @@ -3,8 +3,8 @@ namespace Icinga\Module\Vspheredb\Monitoring\Rule\Definition; use gipfl\Translation\StaticTranslator; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState as State; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState as State; use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; use Icinga\Module\Vspheredb\Monitoring\SingleCheckResult; use Icinga\Util\Format; @@ -19,9 +19,9 @@ public static function prepareState( int $capacity, ?string $instanceName = null ): SingleCheckResult { - $state = new State(); + $state = State::OK; if ($capacity === 0) { - $state->raiseState(CheckPluginState::UNKNOWN); + $state = $state->raise(CheckPluginState::UNKNOWN); return new SingleCheckResult($state, sprintf( '%s free, but got ZERO capacity', Format::bytes($free, Format::STANDARD_IEC) @@ -41,36 +41,34 @@ public static function prepareState( $output = "$instanceName has $output"; } - $percentState = new State(); + $percentState = State::OK; $min = $settings->get('warning_if_less_than_percent_free'); if ($min && ($percentFree < (float) $min)) { - $percentState->raiseState(State::WARNING); + $percentState = $percentState->raise(State::WARNING); } $min = $settings->get('critical_if_less_than_percent_free'); if ($min && ($percentFree < (float) $min)) { - $percentState->raiseState(State::CRITICAL); + $percentState = $percentState->raise(State::CRITICAL); } - $mbState = new State(); + $mbState = State::OK; $mbFree = $free / self::MEGA_BYTE; $min = $settings->get('warning_if_less_than_mbytes_free'); if ($min && ($mbFree < (float) $min)) { - $mbState->raiseState(State::WARNING); + $mbState = $mbState->raise(State::WARNING); } $min = $settings->get('critical_if_less_than_mbytes_free'); if ($min && ($mbFree < (float) $min)) { - $mbState->raiseState(State::CRITICAL); + $mbState = $mbState->raise(State::CRITICAL); } if ($mbState->isProblem() || $percentState->isProblem()) { - if ($settings->get('threshold_precedence') === 'worst_wins') { - $state->raiseState(State::getWorst($percentState, $mbState)); - } else { - $state->raiseState(State::getBest($percentState, $mbState)); - } + $state = $settings->get('threshold_precedence') === 'worst_wins' + ? $state->raise(State::getWorst($percentState, $mbState)) + : $state->raise(State::getBest($percentState, $mbState)); } else { - $state->raiseState($percentState); - $state->raiseState($mbState); + $state = $state->raise($percentState); + $state = $state->raise($mbState); } return new SingleCheckResult($state, $output); @@ -85,25 +83,25 @@ public static function getParameters(): array 'options' => [ '' => $t->translate('- please choose -'), 'best_wins' => $t->translate('Better state wins'), - 'worst_wins' => $t->translate('Worse state wins'), - ], + 'worst_wins' => $t->translate('Worse state wins') + ] ]], 'warning_if_less_than_percent_free' => ['number', [ 'label' => $t->translate('Raise Warning with less than X percent free'), - 'placeholder' => '5', + 'placeholder' => '5' ]], 'critical_if_less_than_percent_free' => ['number', [ 'label' => $t->translate('Raise Critical with less than X percent free'), - 'placeholder' => '2', + 'placeholder' => '2' ]], 'warning_if_less_than_mbytes_free' => ['number', [ 'label' => $t->translate('Raise Warning with less than X MBytes free'), - 'placeholder' => '500', + 'placeholder' => '500' ]], 'critical_if_less_than_mbytes_free' => ['number', [ 'label' => $t->translate('Raise Critical with less than X MBytes free'), - 'placeholder' => '100', - ]], + 'placeholder' => '100' + ]] ]; } } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageRuleDefinition.php index 7b6a57dd..9af4d203 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/MemoryUsageRuleDefinition.php @@ -9,12 +9,13 @@ use Icinga\Module\Vspheredb\DbObject\VmQuickStats; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; +use InvalidArgumentException; class MemoryUsageRuleDefinition extends MonitoringRuleDefinition { public const SUPPORTED_OBJECT_TYPES = [ ObjectType::HOST_SYSTEM, - ObjectType::VIRTUAL_MACHINE, + ObjectType::VIRTUAL_MACHINE ]; public static function getIdentifier(): string @@ -34,7 +35,12 @@ public function getInternalDefaults(): array ]; } - protected function getUsedMemory(BaseDbObject $quickStats) + /** + * @param BaseDbObject $quickStats + * + * @return int + */ + protected function getUsedMemory(BaseDbObject $quickStats): int { if ($quickStats instanceof VmQuickStats) { return $quickStats->get('host_memory_usage_mb') * MemoryUsageHelper::MEGA_BYTE; @@ -53,7 +59,7 @@ public function checkObject(BaseDbObject $object, Settings $settings): array $quickStats = VmQuickStats::loadFor($object); $capacity = $object->get('hardware_memorymb') * MemoryUsageHelper::MEGA_BYTE; } else { - throw new \InvalidArgumentException('Cannot load QuickStats for ' . get_class($object)); + throw new InvalidArgumentException('Cannot load QuickStats for ' . get_class($object)); } $used = $this->getUsedMemory($quickStats); $free = $capacity - $used; diff --git a/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleDefinition.php index 864c7d10..0208edb9 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleDefinition.php @@ -7,6 +7,7 @@ use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; use Icinga\Module\Vspheredb\Monitoring\SingleCheckResult; use ipl\I18n\Translation; +use RuntimeException; use function in_array; @@ -14,10 +15,13 @@ abstract class MonitoringRuleDefinition { use Translation; + /** @var ObjectType[] */ public const SUPPORTED_OBJECT_TYPES = []; abstract public function getLabel(): string; + abstract public static function getIdentifier(): string; + abstract public function getParameters(): array; public static function isMultiInstanceRule(): bool @@ -25,7 +29,7 @@ public static function isMultiInstanceRule(): bool return false; } - public static function supportsObjectType(string $objectType): bool + public static function supportsObjectType(ObjectType $objectType): bool { return in_array($objectType, static::SUPPORTED_OBJECT_TYPES, true); } @@ -33,6 +37,7 @@ public static function supportsObjectType(string $objectType): bool /** * @param BaseDbObject $object * @param Settings $settings + * * @return SingleCheckResult[] */ public function checkObject(BaseDbObject $object, Settings $settings): array @@ -60,14 +65,14 @@ public function getSuggestedSettings(): array return []; } - protected function assertSupportedObject($object) + protected function assertSupportedObject($object): void { - $type = ObjectType::getDbClassType(get_class($object)); + $type = ObjectType::fromDbObject($object); if (!static::supportsObjectType($type)) { - throw new \RuntimeException(sprintf( + throw new RuntimeException(sprintf( "'%s' is not supported. Supported: %s", - $type, - implode(', ', static::SUPPORTED_OBJECT_TYPES) + $type->value, + implode(', ', array_map(fn (ObjectType $t) => $t->value, static::SUPPORTED_OBJECT_TYPES)) )); } } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleSetDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleSetDefinition.php index e67eceb9..2d9eb71c 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleSetDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/MonitoringRuleSetDefinition.php @@ -8,11 +8,11 @@ abstract class MonitoringRuleSetDefinition { use Translation; - /** @var string[]|MonitoringRuleDefinition[] Type hint, these are class names */ + /** @var class-string[] */ public const RULE_CLASSES = []; - /** @var MonitoringRuleDefinition[]|null */ - protected $rules = null; + /** @var ?MonitoringRuleDefinition[] */ + protected ?array $rules = null; /** * @return MonitoringRuleDefinition[] @@ -30,6 +30,7 @@ public function getRules(): array } abstract public function getLabel(): string; + abstract public static function getIdentifier(): string; /** diff --git a/library/Vspheredb/Monitoring/Rule/Definition/ObjectStateRuleSet.php b/library/Vspheredb/Monitoring/Rule/Definition/ObjectStateRuleSet.php index 529bc0a0..000dec50 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/ObjectStateRuleSet.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/ObjectStateRuleSet.php @@ -6,7 +6,7 @@ class ObjectStateRuleSet extends MonitoringRuleSetDefinition { public const RULE_CLASSES = [ VMwareObjectStateRuleDefinition::class, - PowerStateRuleDefinition::class, + PowerStateRuleDefinition::class ]; public function getLabel(): string diff --git a/library/Vspheredb/Monitoring/Rule/Definition/PowerStateRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/PowerStateRuleDefinition.php index a9c0d4bf..b2e7dad6 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/PowerStateRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/PowerStateRuleDefinition.php @@ -8,7 +8,7 @@ use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\DbObject\VmQuickStats; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\MonitoringStateTrigger; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; @@ -19,7 +19,7 @@ class PowerStateRuleDefinition extends MonitoringRuleDefinition { public const SUPPORTED_OBJECT_TYPES = [ ObjectType::HOST_SYSTEM, - ObjectType::VIRTUAL_MACHINE, + ObjectType::VIRTUAL_MACHINE ]; public static function getIdentifier(): string @@ -37,9 +37,7 @@ public function checkObject(BaseDbObject $object, Settings $settings): array if ($object instanceof VirtualMachine) { $what = 'Virtual Machine'; if ($object->get('template') === 'y') { - return [ - new SingleCheckResult(new CheckPluginState(), 'This is a VM template') - ]; + return [new SingleCheckResult(CheckPluginState::OK, 'This is a VM template')]; } } elseif ($object instanceof HostSystem) { $what = 'Host System'; @@ -48,19 +46,15 @@ public function checkObject(BaseDbObject $object, Settings $settings): array } $powerState = $object->get('runtime_power_state'); - if ($powerState === 'poweredOn') { - $state = new CheckPluginState(CheckPluginState::OK); - } else { - $state = MonitoringStateTrigger::getMonitoringState($settings->get("trigger_on_$powerState")); - } + $state = $powerState === 'poweredOn' + ? CheckPluginState::OK + : MonitoringStateTrigger::nullableFrom($settings->get("trigger_on_$powerState"))->monitoringState(); $message = $this->getStatusMessageForPowerState($powerState, $what); - $results = [ - new SingleCheckResult($state, $message) - ]; + $results = [new SingleCheckResult($state, $message)]; if ($powerState === 'poweredOn') { - $uptimeState = new CheckPluginState(); + $uptimeState = CheckPluginState::OK; if ($object instanceof HostSystem) { $stats = HostQuickStats::loadFor($object); } else { @@ -75,13 +69,13 @@ public function checkObject(BaseDbObject $object, Settings $settings): array foreach ( [ - 'warning_for_uptime_less_than_seconds' => CheckPluginState::WARNING, - 'critical_for_uptime_less_than_seconds' => CheckPluginState::CRITICAL, + 'warning_for_uptime_less_than_seconds' => CheckPluginState::WARNING->value, + 'critical_for_uptime_less_than_seconds' => CheckPluginState::CRITICAL->value ] as $setting => $errorState ) { $min = $settings->get($setting); if ($min) { - $this->checkMin($uptimeState, $uptime, $min, $errorState, $info); + $uptimeState = $this->checkMin($uptimeState, $uptime, $min, $errorState, $info); } } @@ -91,13 +85,13 @@ public function checkObject(BaseDbObject $object, Settings $settings): array } foreach ( [ - 'warning_for_uptime_greater_than_days' => CheckPluginState::WARNING, - 'critical_for_uptime_greater_than_days' => CheckPluginState::CRITICAL, + 'warning_for_uptime_greater_than_days' => CheckPluginState::WARNING->value, + 'critical_for_uptime_greater_than_days' => CheckPluginState::CRITICAL->value ] as $setting => $errorState ) { $min = $settings->get($setting); if ($min) { - $this->checkMax($uptimeState, $uptime, $min * 86400, $errorState, $info); + $uptimeState = $this->checkMax($uptimeState, $uptime, $min * 86400, $errorState, $info); } } @@ -113,49 +107,56 @@ public function checkObject(BaseDbObject $object, Settings $settings): array return $results; } - protected function checkMax(CheckPluginState $uptimeState, $value, $threshold, $errorState, &$info) - { - if ($threshold) { - if ($value >= $threshold) { - $uptimeState->raiseState($errorState); - $info = sprintf('>= %s ago', DateFormatter::formatDuration($threshold)); - } + protected function checkMax( + CheckPluginState $uptimeState, + int $value, + int $threshold, + int $errorState, + ?string &$info + ): CheckPluginState { + if ($value >= $threshold) { + $info = sprintf('>= %s ago', DateFormatter::formatDuration($threshold)); + + return $uptimeState->raise(CheckPluginState::from($errorState)); } + + return $uptimeState; } - protected function checkMin(CheckPluginState $uptimeState, $value, $threshold, $errorState, &$info) - { - if ($threshold) { - if ($value < $threshold) { - $uptimeState->raiseState($errorState); - $info = sprintf('less than %s ago', DateFormatter::formatDuration($threshold)); - } + protected function checkMin( + CheckPluginState $uptimeState, + int $value, + int $threshold, + int $errorState, + ?string &$info + ): CheckPluginState { + if ($value < $threshold) { + $info = sprintf('less than %s ago', DateFormatter::formatDuration($threshold)); + + return $uptimeState->raise(CheckPluginState::from($errorState)); } + + return $uptimeState; } - protected function getStatusMessageForPowerState($state, $what): string + protected function getStatusMessageForPowerState(string $state, string $what): string { - switch ($state) { - case 'poweredOff': - return "$what has been powered off"; - case 'suspended': - return "$what has been suspended"; - case 'unknown': - return "$what power state is unknown, might be disconnected"; - case 'poweredOn': - return "$what is powered on"; - } - - throw new InvalidArgumentException("'$state' is not a known power state"); + return match ($state) { + 'poweredOff' => "$what has been powered off", + 'suspended' => "$what has been suspended", + 'unknown' => "$what power state is unknown, might be disconnected", + 'poweredOn' => "$what is powered on", + default => throw new InvalidArgumentException("'$state' is not a known power state") + }; } public function getInternalDefaults(): array { return [ - 'trigger_on_poweredOff' => MonitoringStateTrigger::RAISE_CRITICAL, - 'trigger_on_suspended' => MonitoringStateTrigger::RAISE_CRITICAL, - 'trigger_on_unknown' => MonitoringStateTrigger::RAISE_UNKNOWN, - 'warning_for_uptime_less_than' => 900, + 'trigger_on_poweredOff' => MonitoringStateTrigger::RAISE_CRITICAL->value, + 'trigger_on_suspended' => MonitoringStateTrigger::RAISE_CRITICAL->value, + 'trigger_on_unknown' => MonitoringStateTrigger::RAISE_UNKNOWN->value, + 'warning_for_uptime_less_than' => 900 ]; } @@ -163,31 +164,31 @@ public function getParameters(): array { return [ 'trigger_on_poweredOff' => ['state_trigger', [ - 'label' => $this->translate('When powered off'), + 'label' => $this->translate('When powered off') ]], 'trigger_on_suspended' => ['state_trigger', [ - 'label' => $this->translate('When suspended'), + 'label' => $this->translate('When suspended') ]], 'trigger_on_unknown' => ['state_trigger', [ 'label' => $this->translate('When unknown'), - 'description' => $this->translate('Might be disconnected'), + 'description' => $this->translate('Might be disconnected') ]], 'warning_for_uptime_less_than' => ['number', [ 'label' => $this->translate('Raise WARNING for uptime less than'), - 'description' => $this->translate('Please provide the uptime in seconds'), + 'description' => $this->translate('Please provide the uptime in seconds') ]], 'critical_for_uptime_less_than' => ['number', [ 'label' => $this->translate('Raise CRITICAL for uptime less than'), - 'description' => $this->translate('Please provide the uptime in seconds'), + 'description' => $this->translate('Please provide the uptime in seconds') ]], 'warning_for_uptime_greater_than_days' => ['number', [ 'label' => $this->translate('Raise WARNING for uptime greater than'), - 'description' => $this->translate('Please provide the uptime in days'), + 'description' => $this->translate('Please provide the uptime in days') ]], 'critical_for_uptime_greater_than_days' => ['number', [ 'label' => $this->translate('Raise CRITICAL for uptime greater than'), - 'description' => $this->translate('Please provide the uptime in days'), - ]], + 'description' => $this->translate('Please provide the uptime in days') + ]] ]; } } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/RuleSetRegistry.php b/library/Vspheredb/Monitoring/Rule/Definition/RuleSetRegistry.php index 609782a3..396726aa 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/RuleSetRegistry.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/RuleSetRegistry.php @@ -3,20 +3,22 @@ namespace Icinga\Module\Vspheredb\Monitoring\Rule\Definition; use gipfl\Json\JsonSerialization; +use InvalidArgumentException; use RuntimeException; +use stdClass; class RuleSetRegistry implements JsonSerialization { - protected static $allSets = [ + protected static array $allSets = [ ObjectStateRuleSet::class, ComputeResourceUsageRuleSet::class, DiskHealthRuleSet::class, DatastoreHealthRuleSet::class, - ConfigurationPolicyRuleSet::class, + ConfigurationPolicyRuleSet::class ]; /** @var MonitoringRuleSetDefinition[] */ - protected $sets = []; + protected array $sets = []; /** * @param string[]|MonitoringRuleSetDefinition[] $sets @@ -36,7 +38,7 @@ public function getSets(): array return $this->sets; } - public static function byName(string $name): RuleSetRegistry + public static function byName(string $name): static { /** @var string|MonitoringRuleSetDefinition $class */ foreach (self::$allSets as $class) { @@ -45,15 +47,15 @@ public static function byName(string $name): RuleSetRegistry } } - throw new \InvalidArgumentException("There is no Rule Set named '$name'"); + throw new InvalidArgumentException("There is no Rule Set named '$name'"); } - public static function default(): RuleSetRegistry + public static function default(): static { return new static(self::$allSets); } - public function loadSet(string $class) + public function loadSet(string $class): void { $set = new $class(); /** @var string $name */ @@ -65,12 +67,12 @@ public function loadSet(string $class) $this->sets[$name] = $set; } - public static function fromSerialization($any): RuleSetRegistry + public static function fromSerialization(mixed $any): static { return new static((array) $any); } - public function jsonSerialize(): \stdClass + public function jsonSerialize(): stdClass { $result = []; foreach ($this->sets as $set) { diff --git a/library/Vspheredb/Monitoring/Rule/Definition/SnapshotsRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/SnapshotsRuleDefinition.php index ad792b00..75a0e6a2 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/SnapshotsRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/SnapshotsRuleDefinition.php @@ -3,16 +3,14 @@ namespace Icinga\Module\Vspheredb\Monitoring\Rule\Definition; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Monitoring\Rule\Settings; use Icinga\Module\Vspheredb\Monitoring\SingleCheckResult; class SnapshotsRuleDefinition extends MonitoringRuleDefinition { - public const SUPPORTED_OBJECT_TYPES = [ - ObjectType::VIRTUAL_MACHINE, - ]; + public const SUPPORTED_OBJECT_TYPES = [ObjectType::VIRTUAL_MACHINE]; public static function getIdentifier(): string { @@ -27,10 +25,10 @@ public function getLabel(): string public function getInternalDefaults(): array { return [ - 'warning_if_more_than' => 1, - 'critical_if_more_than' => 5, - 'warning_if_older_than' => 7, // Days - 'critical_if_older_than' => 30, + 'warning_if_more_than' => 1, + 'critical_if_more_than' => 5, + 'warning_if_older_than' => 7, // Days + 'critical_if_older_than' => 30 ]; } @@ -42,7 +40,7 @@ public function checkObject(BaseDbObject $object, Settings $settings): array 'cnt' => 'COUNT(*)', 'ts_oldest' => 'FLOOR(MIN(ts_create) / 1000)' ])->where('vm_snapshot.vm_uuid = ?', $object->getConnection()->quoteBinary($object->get('uuid')))); - $state = new CheckPluginState(); + $state = CheckPluginState::OK; $count = (int) $info->cnt; if ($count === 0) { @@ -50,19 +48,19 @@ public function checkObject(BaseDbObject $object, Settings $settings): array } else { $max = $settings->get('warning_if_more_than'); if ($max && $count > $max) { - $state->raiseState(CheckPluginState::WARNING); + $state = $state->raise(CheckPluginState::WARNING); } $max = $settings->get('critical_if_more_than'); if ($max && $count > $max) { - $state->raiseState(CheckPluginState::CRITICAL); + $state = $state->raise(CheckPluginState::CRITICAL); } $min = $settings->get('warning_if_older_than'); if ($min && $info->ts_oldest < (time() - $min * 86400)) { - $state->raiseState(CheckPluginState::WARNING); + $state = $state->raise(CheckPluginState::WARNING); } $min = $settings->get('critical_if_older_than'); if ($min && $info->ts_oldest < (time() - $min * 86400)) { - $state->raiseState(CheckPluginState::CRITICAL); + $state = $state->raise(CheckPluginState::CRITICAL); } $name = $db->fetchOne( $db->select()->from('vm_snapshot', 'name') @@ -76,9 +74,7 @@ public function checkObject(BaseDbObject $object, Settings $settings): array date('Y-m-d H:i', $info->ts_oldest) ); } - return [ - new SingleCheckResult($state, $output) - ]; + return [new SingleCheckResult($state, $output)]; } public function getParameters(): array @@ -86,20 +82,20 @@ public function getParameters(): array return [ 'warning_if_more_than' => ['number', [ 'label' => $this->translate('Raise Warning if more than X snapshots'), - 'placeholder' => 'unset', + 'placeholder' => 'unset' ]], 'critical_if_more_than' => ['number', [ 'label' => $this->translate('Raise Critical if more than X snapshots'), - 'placeholder' => 'unset', + 'placeholder' => 'unset' ]], 'warning_if_older_than' => ['number', [ 'label' => $this->translate('Raise Warning for snapshots older than X days'), - 'placeholder' => 'unset', + 'placeholder' => 'unset' ]], 'critical_if_older_than' => ['number', [ 'label' => $this->translate('Raise Critical for snapshots older than X days'), - 'placeholder' => 'unset', - ]], + 'placeholder' => 'unset' + ]] ]; } } diff --git a/library/Vspheredb/Monitoring/Rule/Definition/VMwareObjectStateRuleDefinition.php b/library/Vspheredb/Monitoring/Rule/Definition/VMwareObjectStateRuleDefinition.php index 55b1256e..68406868 100644 --- a/library/Vspheredb/Monitoring/Rule/Definition/VMwareObjectStateRuleDefinition.php +++ b/library/Vspheredb/Monitoring/Rule/Definition/VMwareObjectStateRuleDefinition.php @@ -14,7 +14,7 @@ class VMwareObjectStateRuleDefinition extends MonitoringRuleDefinition public const SUPPORTED_OBJECT_TYPES = [ ObjectType::HOST_SYSTEM, ObjectType::VIRTUAL_MACHINE, - ObjectType::DATASTORE, + ObjectType::DATASTORE ]; public static function getIdentifier(): string @@ -32,15 +32,13 @@ public function checkObject(BaseDbObject $object, Settings $settings): array try { $color = $object->object()->get('overall_status'); $message = $this->getStatusMessageForColor($color); - } catch (NotFoundError $e) { + } catch (NotFoundError) { $color = 'gray'; $message = 'Could not find the related Managed Object, please check my vCenter permissions'; } - $state = MonitoringStateTrigger::getMonitoringState($settings->get("trigger_on_$color")); + $state = MonitoringStateTrigger::nullableFrom($settings->get("trigger_on_$color"))->monitoringState(); - return [ - new SingleCheckResult($state, $message) - ]; + return [new SingleCheckResult($state, $message)]; } protected function getStatusMessageForColor($color): string @@ -56,9 +54,9 @@ protected function getStatusMessageForColor($color): string public function getInternalDefaults(): array { return [ - 'trigger_on_gray' => MonitoringStateTrigger::RAISE_CRITICAL, - 'trigger_on_yellow' => MonitoringStateTrigger::RAISE_WARNING, - 'trigger_on_red' => MonitoringStateTrigger::RAISE_CRITICAL + 'trigger_on_gray' => MonitoringStateTrigger::RAISE_CRITICAL->value, + 'trigger_on_yellow' => MonitoringStateTrigger::RAISE_WARNING->value, + 'trigger_on_red' => MonitoringStateTrigger::RAISE_CRITICAL->value ]; } @@ -66,15 +64,15 @@ public function getParameters(): array { return [ 'trigger_on_yellow' => ['state_trigger', [ - 'label' => $this->translate('When VMware shows YELLOW'), + 'label' => $this->translate('When VMware shows YELLOW') ]], 'trigger_on_gray' => ['state_trigger', [ 'label' => $this->translate('When VMware shows GRAY'), 'description' => $this->translate('VM might be unreachable') ]], 'trigger_on_red' => ['state_trigger', [ - 'label' => $this->translate('When VMware shows RED'), - ]], + 'label' => $this->translate('When VMware shows RED') + ]] ]; } } diff --git a/library/Vspheredb/Monitoring/Rule/Enum/CheckPluginState.php b/library/Vspheredb/Monitoring/Rule/Enum/CheckPluginState.php new file mode 100644 index 00000000..133c5f62 --- /dev/null +++ b/library/Vspheredb/Monitoring/Rule/Enum/CheckPluginState.php @@ -0,0 +1,104 @@ + 0, + self::WARNING => 1, + self::CRITICAL => 3, + self::UNKNOWN => 2 + }; + } + + public function color(): string + { + return match ($this) { + self::OK => 'green', + self::WARNING => 'brown', + self::CRITICAL => 'red', + self::UNKNOWN => 'purple' + }; + } + + public static function fromTrigger(MonitoringStateTrigger $trigger): self + { + foreach (CheckPluginState::cases() as $case) { + if ($case->name === strtoupper($trigger->value)) { + return $case; + } + } + + throw new InvalidArgumentException("$trigger->value is not a valid state name"); + } + + /** + * @param CheckPluginState $state + * + * @return self + */ + public function raise(CheckPluginState $state): self + { + if ($state->sortValue() > self::sortValue()) { + return $state; + } + + return $this; + } + + public function isProblem(): bool + { + return $this !== CheckPluginState::OK; + } + + public static function compare(CheckPluginState $left, CheckPluginState $right): int + { + return $left->sortValue() <=> $right->sortValue(); + } + + public static function getBest(CheckPluginState ...$states): CheckPluginState + { + $formerState = array_shift($states); + if ($formerState === null) { + throw new RuntimeException('Comparing an empty state list is not possible'); + } + while ($state = array_shift($states)) { + if (self::compare($formerState, $state) === 1) { + $formerState = $state; + } + } + + return $formerState; + } + + public static function getWorst(CheckPluginState ...$states): CheckPluginState + { + $formerState = array_shift($states); + if ($formerState === null) { + throw new RuntimeException('Comparing an empty state list is not possible'); + } + while ($state = array_shift($states)) { + if (self::compare($formerState, $state) === -1) { + $formerState = $state; + } + } + + return $formerState; + } + + public function getExitCode(): int + { + return $this->value; + } +} diff --git a/library/Vspheredb/Monitoring/Rule/Enum/MonitoringStateTrigger.php b/library/Vspheredb/Monitoring/Rule/Enum/MonitoringStateTrigger.php index dc51d4f5..37f12468 100644 --- a/library/Vspheredb/Monitoring/Rule/Enum/MonitoringStateTrigger.php +++ b/library/Vspheredb/Monitoring/Rule/Enum/MonitoringStateTrigger.php @@ -2,24 +2,41 @@ namespace Icinga\Module\Vspheredb\Monitoring\Rule\Enum; -use Icinga\Module\Vspheredb\Monitoring\CheckPluginState; - -class MonitoringStateTrigger +enum MonitoringStateTrigger: string { - public const IGNORE = 'ignore'; - public const RAISE_WARNING = 'warning'; - public const RAISE_CRITICAL = 'critical'; - public const RAISE_UNKNOWN = 'unknown'; + case IGNORE = 'ignore'; + case RAISE_WARNING = 'warning'; + case RAISE_CRITICAL = 'critical'; + case RAISE_UNKNOWN = 'unknown'; - public static function getMonitoringState(?string $trigger): CheckPluginState + /** + * Allow to create a trigger out of null. Null leads to the IGNORE case. + * + * @param ?string $from + * + * @return self + */ + public static function nullableFrom(?string $from): self { - switch ($trigger) { - case self::RAISE_WARNING: - case self::RAISE_CRITICAL: - case self::RAISE_UNKNOWN: - return new CheckPluginState($trigger); + if ($from === null) { + return self::IGNORE; } - return new CheckPluginState(); + return self::from($from); + } + + /** + * Get the monitoring state for the trigger + * + * @return CheckPluginState + */ + public function monitoringState(): CheckPluginState + { + return match ($this) { + self::RAISE_WARNING => CheckPluginState::fromTrigger(self::RAISE_WARNING), + self::RAISE_CRITICAL => CheckPluginState::fromTrigger(self::RAISE_CRITICAL), + self::RAISE_UNKNOWN => CheckPluginState::fromTrigger(self::RAISE_UNKNOWN), + default => CheckPluginState::OK + }; } } diff --git a/library/Vspheredb/Monitoring/Rule/Enum/ObjectType.php b/library/Vspheredb/Monitoring/Rule/Enum/ObjectType.php index 655d47e7..5a2468e9 100644 --- a/library/Vspheredb/Monitoring/Rule/Enum/ObjectType.php +++ b/library/Vspheredb/Monitoring/Rule/Enum/ObjectType.php @@ -6,48 +6,100 @@ use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; +use InvalidArgumentException; +use RuntimeException; -class ObjectType +enum ObjectType: string { - // No enum, not yet. - public const HOST_SYSTEM = 'host'; - public const VIRTUAL_MACHINE = 'vm'; - public const DATASTORE = 'datastore'; - - public const TYPES = [ - self::HOST_SYSTEM, - self::VIRTUAL_MACHINE, - self::DATASTORE, - ]; - - public const TYPE_CLASSES = [ - self::HOST_SYSTEM => HostSystem::class, - self::VIRTUAL_MACHINE => VirtualMachine::class, - self::DATASTORE => Datastore::class, - ]; - - public const DB_CLASS_TYPE = [ - HostSystem::class => self::HOST_SYSTEM, - VirtualMachine::class => self::VIRTUAL_MACHINE, - Datastore::class => self::DATASTORE, - ]; - - public static function getDbObjectType(BaseDbObject $object): string + case HOST_SYSTEM = 'host'; + case VIRTUAL_MACHINE = 'vm'; + case DATASTORE = 'datastore'; + + /** + * Create an ObjectType from a database object + * + * @param BaseDbObject $object + * + * @return self + */ + public static function fromDbObject(BaseDbObject $object): self + { + $dbClass = $object::class; + + return match ($dbClass) { + HostSystem::class => self::HOST_SYSTEM, + VirtualMachine::class => self::VIRTUAL_MACHINE, + Datastore::class => self::DATASTORE, + default => throw new RuntimeException("'$dbClass' is not supported (1)") + }; + } + + /** + * Create an ObjectType from a URL param + */ + public static function fromParam(string $objectTypeParam): self + { + return match ($objectTypeParam) { + 'HostSystem' => self::HOST_SYSTEM, + 'VirtualMachine' => self::VIRTUAL_MACHINE, + 'Datastore' => self::DATASTORE, + default => throw new InvalidArgumentException('Unsupported object type: ' . $objectTypeParam) + }; + } + + /** + * Get the label for the object type + * + * @return string + */ + public function label(): string { - return static::getDbClassType(get_class($object)); + return match ($this) { + self::HOST_SYSTEM => 'Host System', + self::VIRTUAL_MACHINE => 'Virtual Machine', + self::DATASTORE => 'Datastore' + }; } /** - * @param string $dbClass + * Get the URL for the object type * * @return string */ - public static function getDbClassType(string $dbClass): string + public function url(): string { - if (isset(self::DB_CLASS_TYPE[$dbClass])) { - return self::DB_CLASS_TYPE[$dbClass]; - } + return match ($this) { + self::HOST_SYSTEM => 'vspheredb/host', + self::VIRTUAL_MACHINE => 'vspheredb/vm', + self::DATASTORE => 'vspheredb/datastore', + }; + } - throw new \RuntimeException("'$dbClass' is not supported (1)"); + /** + * Get the class for the object type + * + * @return class-string + */ + public function class(): string + { + return match ($this) { + self::HOST_SYSTEM => HostSystem::class, + self::VIRTUAL_MACHINE => VirtualMachine::class, + self::DATASTORE => Datastore::class, + }; + } + + /** + * Get the table for the object type + * + * @return string + */ + public function table(): string + { + return match ($this) { + self::HOST_SYSTEM => 'host_system', + self::VIRTUAL_MACHINE => 'virtual_machine', + self::DATASTORE => 'datastore', + }; } } diff --git a/library/Vspheredb/Monitoring/Rule/Enum/ResultStatus.php b/library/Vspheredb/Monitoring/Rule/Enum/ResultStatus.php new file mode 100644 index 00000000..7815abdb --- /dev/null +++ b/library/Vspheredb/Monitoring/Rule/Enum/ResultStatus.php @@ -0,0 +1,11 @@ +settings as $key => $value) { $this->setInherited($key, $value, $inheritedFrom); @@ -83,9 +83,10 @@ public function dump(): array /** * @param string $prefix + * * @return $this|InheritedSettings */ - public function withRemovedPrefix(string $prefix) + public function withRemovedPrefix(string $prefix): InheritedSettings { $length = strlen($prefix); $settings = new InheritedSettings($this->tree); @@ -111,7 +112,7 @@ public function listMainInheritedKeys(): array return array_keys($keys); } - public function setInternalDefaults(RuleSetRegistry $registry) + public function setInternalDefaults(RuleSetRegistry $registry): void { foreach ($registry->getSets() as $set) { foreach ($set->getRules() as $rule) { @@ -131,12 +132,12 @@ public function setInternalDefaults(RuleSetRegistry $registry) /** * @param string $name - * @param $value - * @param $inheritedFrom + * @param mixed $value + * @param ?string $inheritedFrom * * @return void */ - public function setInherited(string $name, $value, $inheritedFrom = null): void + public function setInherited(string $name, mixed $value, ?string $inheritedFrom = null): void { if ($this->get($name) !== null) { return; diff --git a/library/Vspheredb/Monitoring/Rule/InstanceKeys.php b/library/Vspheredb/Monitoring/Rule/InstanceKeys.php index baa48294..62d790e8 100644 --- a/library/Vspheredb/Monitoring/Rule/InstanceKeys.php +++ b/library/Vspheredb/Monitoring/Rule/InstanceKeys.php @@ -12,7 +12,8 @@ class InstanceKeys /** * @param array $values * @param RuleSet $set - * @param Rule|null $rule + * @param Rule $rule + * * @return UuidInterface[] List of UUIDs */ public static function getListFrom(array $values, RuleSet $set, Rule $rule): array diff --git a/library/Vspheredb/Monitoring/Rule/MonitoringRule.php b/library/Vspheredb/Monitoring/Rule/MonitoringRule.php index f4795f6f..ff89c09a 100644 --- a/library/Vspheredb/Monitoring/Rule/MonitoringRule.php +++ b/library/Vspheredb/Monitoring/Rule/MonitoringRule.php @@ -7,10 +7,9 @@ class MonitoringRule implements JsonSerialization { - protected $enabled = true; + protected bool $enabled = true; - /** @var MonitoringRuleSetDefinition */ - protected $definition; + protected MonitoringRuleSetDefinition $definition; public function __construct(MonitoringRuleSetDefinition $definition) { diff --git a/library/Vspheredb/Monitoring/Rule/MonitoringRuleSet.php b/library/Vspheredb/Monitoring/Rule/MonitoringRuleSet.php index 9c96e534..d1d5a0b7 100644 --- a/library/Vspheredb/Monitoring/Rule/MonitoringRuleSet.php +++ b/library/Vspheredb/Monitoring/Rule/MonitoringRuleSet.php @@ -9,35 +9,27 @@ class MonitoringRuleSet { public const TABLE = 'monitoring_rule_set'; + public const NO_OBJECT = ''; - /** @var string */ - protected $binaryUuid; + protected string $binaryUuid; - /** @var string */ - protected $objectFolder; + protected string $objectFolder; - /** @var ?bool */ - protected $enabled = null; + protected ?bool $enabled = null; - /** @var MonitoringRuleSetDefinition */ - protected $definition; + protected ?MonitoringRuleSetDefinition $definition = null; - /** @var Settings */ - protected $settings; + protected Settings $settings; - protected $fromDb = false; + protected bool $fromDb = false; - protected static $preloadCache = null; + protected static ?array $preloadCache = null; public function __construct(string $binaryUuid, string $objectFolder, ?Settings $settings = null) { $this->binaryUuid = $binaryUuid; - if ($settings === null) { - $this->settings = new Settings(); - } else { - $this->settings = $settings; - } + $this->settings = $settings ?? new Settings(); $this->objectFolder = $objectFolder; } @@ -64,27 +56,28 @@ public static function loadOptionalForUuid(string $uuid, string $objectFolder, D return null; } - protected static function makeKey($objectUuid, $objectFolder): string + protected static function makeKey(?string $objectUuid, string $objectFolder): string { // correct would be using UUID, but bin2hex() is faster, and this is internal only - return ($objectUuid === null ? 'null' : bin2hex($objectUuid)) - . '|' - . json_encode($objectFolder); + return ($objectUuid === null ? 'null' : bin2hex($objectUuid)) . '|' . json_encode($objectFolder); } - public static function preloadAll(Db $connection) + public static function preloadAll(Db $connection): void { $db = $connection->getDbAdapter(); self::$preloadCache = []; foreach ($db->fetchAll($db->select()->from(MonitoringRuleSet::TABLE)) as $row) { $uuid = $row->object_uuid; $folder = $row->object_folder; - self::$preloadCache[self::makeKey($uuid, $folder)] - = new static($uuid, $folder, Settings::fromSerialization(JsonString::decode($row->settings))); + self::$preloadCache[self::makeKey($uuid, $folder)] = new static( + $uuid, + $folder, + Settings::fromSerialization(JsonString::decode($row->settings)) + ); } } - public static function clearPreloadCache() + public static function clearPreloadCache(): void { self::$preloadCache = null; } @@ -109,7 +102,7 @@ public function store(Db $connection): bool $db->insert(MonitoringRuleSet::TABLE, [ 'object_uuid' => $this->binaryUuid, 'object_folder' => $this->objectFolder, - 'settings' => JsonString::encode($this->settings), + 'settings' => JsonString::encode($this->settings) ]); $this->fromDb = true; @@ -121,10 +114,7 @@ public function delete(Db $connection): bool $existing = self::loadOptionalForUuid($this->binaryUuid, $this->objectFolder, $connection); $db = $connection->getDbAdapter(); if ($existing) { - $rowCount = $db->delete( - MonitoringRuleSet::TABLE, - $this->createWhere($connection) - ); + $rowCount = $db->delete(MonitoringRuleSet::TABLE, $this->createWhere($connection)); $this->fromDb = false; return $rowCount > 0; @@ -151,9 +141,9 @@ public function hasBeenLoadedFromDb(): bool } /** - * @return MonitoringRuleSetDefinition + * @return ?MonitoringRuleSetDefinition */ - public function getDefinition(): MonitoringRuleSetDefinition + public function getDefinition(): ?MonitoringRuleSetDefinition { return $this->definition; } @@ -168,6 +158,7 @@ public function getSettings(): Settings /** * @param Settings $settings + * * @return MonitoringRuleSet */ public function setSettings(Settings $settings): MonitoringRuleSet diff --git a/library/Vspheredb/Monitoring/Rule/MonitoringRulesTree.php b/library/Vspheredb/Monitoring/Rule/MonitoringRulesTree.php index c3c66c0a..a321a511 100644 --- a/library/Vspheredb/Monitoring/Rule/MonitoringRulesTree.php +++ b/library/Vspheredb/Monitoring/Rule/MonitoringRulesTree.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Monitoring\Rule; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use ipl\I18n\Translation; @@ -12,22 +13,17 @@ class MonitoringRulesTree public const ROOT_OBJECT_TYPE = 'root'; - /** @var Db */ - protected $db; + protected ?Db $db; - /** @var string */ - protected $baseObjectFolderName; + protected string $baseObjectFolderName; - /** @var ?array */ - protected $fetchedTree; + protected ?array $fetchedTree = null; - /** @var ?array */ - protected $configList; + protected ?array $configList = null; - /** @var ?array */ - protected $allNodes; + protected ?array $allNodes = null; - public function __construct(Db $db, $baseObjectFolderName) + public function __construct(Db $db, string $baseObjectFolderName) { $this->db = $db; $this->baseObjectFolderName = $baseObjectFolderName; @@ -76,7 +72,7 @@ public function listParentUuidsFor(string $uuid): array return $parents; } - public function getRootNode() + public function getRootNode(): object { return (object) [ 'object_name' => $this->translate('All vCenters'), @@ -101,7 +97,7 @@ public function hasConfigurationForUuid(string $uuid): bool } /** - * @throws \Icinga\Exception\NotFoundError + * @throws NotFoundError */ public function getInheritedSettingsFor(BaseDbObject $object): InheritedSettings { @@ -161,11 +157,7 @@ protected function listAllConfiguredRuleSets(): array protected function getTree(): array { - if ($this->fetchedTree === null) { - $this->fetchedTree = $this->fetchTree(); - } - - return $this->fetchedTree; + return $this->fetchedTree ??= $this->fetchTree(); } protected function fetchTree(): array @@ -202,7 +194,7 @@ protected function fetchTree(): array return $root; } - public function discard() + public function discard(): void { $this->allNodes = null; $this->fetchedTree = null; diff --git a/library/Vspheredb/Monitoring/Rule/MonitoringRulesTreeRenderer.php b/library/Vspheredb/Monitoring/Rule/MonitoringRulesTreeRenderer.php index d15028bf..fb3d938f 100644 --- a/library/Vspheredb/Monitoring/Rule/MonitoringRulesTreeRenderer.php +++ b/library/Vspheredb/Monitoring/Rule/MonitoringRulesTreeRenderer.php @@ -17,25 +17,25 @@ class MonitoringRulesTreeRenderer extends BaseHtmlElement protected $defaultAttributes = [ 'class' => 'tree', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - /** @var MonitoringRulesTree */ - protected $tree; - protected $url; + protected MonitoringRulesTree $tree; - public function __construct(MonitoringRulesTree $tree, $url) + protected string $url; + + public function __construct(MonitoringRulesTree $tree, string $url) { $this->tree = $tree; $this->url = $url; } - protected function assemble() + protected function assemble(): void { $this->add($this->buildTree($this->tree->getRootNode())); } - protected function buildTree($node, $level = 0): HtmlElement + protected function buildTree(object $node, $level = 0): HtmlElement { $hasChildren = ! empty($node->children); $li = Html::tag('li'); @@ -63,14 +63,8 @@ protected function buildTree($node, $level = 0): HtmlElement return $li; } - protected function createLink($label, $uuid = null, $attributes = []): Link + protected function createLink(string $label, ?string $uuid = null, array $attributes = []): Link { - if ($uuid === null) { - $params = []; - } else { - $params = Util::uuidParams($uuid); - } - - return Link::create($label, $this->url, $params, $attributes); + return Link::create($label, $this->url, $uuid === null ? [] : Util::uuidParams($uuid), $attributes); } } diff --git a/library/Vspheredb/Monitoring/Rule/RuleForm.php b/library/Vspheredb/Monitoring/Rule/RuleForm.php index 3bdf44c2..6d8a5849 100644 --- a/library/Vspheredb/Monitoring/Rule/RuleForm.php +++ b/library/Vspheredb/Monitoring/Rule/RuleForm.php @@ -8,7 +8,10 @@ use Icinga\Module\Vspheredb\Monitoring\Rule\Definition\MonitoringRuleSetDefinition as RuleSet; use Icinga\Module\Vspheredb\Monitoring\Rule\Definition\RuleSetRegistry; use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\MonitoringStateTrigger; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ResultStatus; use InvalidArgumentException; +use ipl\Html\Attributes; use ipl\Html\FormElement\NumberElement; use ipl\Html\FormElement\SelectElement; use ipl\Html\FormElement\TextElement; @@ -16,44 +19,36 @@ use ipl\I18n\Translation; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use RuntimeException; class RuleForm extends Form { use Translation; public const NEXT_UUID = '00000000-0000-0000-0000-000000000000'; - public const RESULT_CREATED = 'created'; - public const RESULT_MODIFIED = 'modified'; - public const RESULT_UNMODIFIED = 'unmodified'; - public const RESULT_DELETED = 'deleted'; - /** @var string */ - protected $objectType; + protected ObjectType $objectType; - /** @var string */ - protected $binaryUuid; + protected string $binaryUuid; - /** @var Db */ - protected $db; + protected Db $db; - /** @var InheritedSettings */ - protected $inherited; + protected InheritedSettings $inherited; - /** @var MonitoringRuleSet|null */ - protected $loadedSet; + protected ?MonitoringRuleSet $loadedSet; - /** @var string Any of self::RESULT_* */ - protected $result; + /** @var ?ResultStatus Any of self::RESULT_* */ + protected ?ResultStatus $result = null; public function __construct( - string $objectType, + ObjectType $objectType, string $binaryUuid, Db $db, InheritedSettings $inherited, ?MonitoringRuleSet $loadedSet = null ) { $this->addPluginLoader('element', '\\Icinga\\Module\\Vspheredb\\Monitoring\\Rule\\Form\\Element', 'Element'); - $this->addAttributes(['class' => 'ruleform']); + $this->addAttributes(Attributes::create(['class' => 'ruleform'])); $this->objectType = $objectType; $this->db = $db; $this->binaryUuid = $binaryUuid; @@ -64,7 +59,7 @@ public function __construct( } } - protected function assemble() + protected function assemble(): void { $sets = RuleSetRegistry::default()->getSets(); foreach ($sets as $set) { @@ -108,16 +103,15 @@ protected function assemble() $this->applyInheritedInfo(); } - protected function addRule(RuleSet $set, Rule $rule, ?UuidInterface $instance = null) + protected function addRule(RuleSet $set, Rule $rule, ?UuidInterface $instance = null): void { if ($instance === null) { $this->add(Html::tag('h3', $rule->getLabel())); } else { - if ($instance->toString() === self::NEXT_UUID) { - $this->add(Html::tag('h3', $rule->getLabel() . sprintf(' (%s)', $this->translate('new instance')))); - } else { - $this->add(Html::tag('h3', $rule->getLabel() . sprintf(' (%s)', $instance->toString()))); - } + $uuid = $instance->toString() === self::NEXT_UUID + ? $this->translate('new instance') + : $instance->toString(); + $this->add(Html::tag('h3', $rule->getLabel() . sprintf(' (%s)', $uuid))); } $prefix = Settings::prefix($set, $rule, $instance); $this->addEnabledSetting($prefix); @@ -128,7 +122,7 @@ protected function addRule(RuleSet $set, Rule $rule, ?UuidInterface $instance = } } - protected function createRuleElement($elementName, $definition) + protected function createRuleElement($elementName, $definition): void { $elementType = array_shift($definition); $options = array_shift($definition) ?: []; @@ -140,14 +134,14 @@ protected function createRuleElement($elementName, $definition) } } - protected function applyInheritedInfo() + protected function applyInheritedInfo(): void { foreach ((array) $this->inherited->jsonSerialize() as $key => $value) { $this->setInheritedValue($key, $value, $this->inherited->getInheritedFromName($key)); } } - protected function setInheritedValue($elementName, $value, $sourceName = null) + protected function setInheritedValue(string $elementName, mixed $value, ?string $sourceName = null): void { if ($this->getValue($elementName) !== null) { return; @@ -178,7 +172,7 @@ protected function setInheritedValue($elementName, $value, $sourceName = null) } } - protected function assertValidateParameterName($name) + protected function assertValidateParameterName($name): void { if (! preg_match('/^[A-z]+[A-z0-9_]*$/', $name)) { throw new InvalidArgumentException("'$name' is not a valid parameter name"); @@ -230,8 +224,13 @@ public function getNormalizedValues(): array return $result; } - protected function applyResultValue(&$values, $prefix, $key, $elementType, $storingPrefix = null) - { + protected function applyResultValue( + array &$values, + string $prefix, + string $key, + string $elementType, + ?string $storingPrefix = null + ): void { $storingKey = ($storingPrefix ?? $prefix) . $key; $key = $prefix . $key; $value = $this->getValue($key); @@ -243,67 +242,61 @@ protected function applyResultValue(&$values, $prefix, $key, $elementType, $stor } } - protected function normalizeBoolean($value): ?bool + protected function normalizeBoolean(?string $value): ?bool { - switch ($value) { - case null: - return null; - case 'y': - return true; - case 'n': - return false; - } - - throw new \RuntimeException("'$value' is not a valid boolean value"); + return match ($value) { + null => null, + 'y' => true, + 'n' => false, + default => throw new RuntimeException("'$value' is not a valid boolean value") + }; } - protected function addEnabledSetting($prefix) + protected function addEnabledSetting(string $prefix): void { $elementName = $prefix . Settings::KEY_ENABLED; $this->addElement('boolean', $elementName, [ 'label' => $this->translate('Enabled'), - // 'class' => 'autosubmit', + // 'class' => 'autosubmit' ]); $this->setInheritedValue($elementName, true); } - protected function addStateTriggerElement(string $name, $options = []) + protected function addStateTriggerElement(string $name, array $options = []): void { $selectOptions = [ '' => $this->translate('Not configured / Inherited'), - MonitoringStateTrigger::IGNORE => $this->translate('Do nothing'), - MonitoringStateTrigger::RAISE_WARNING => $this->translate('Trigger a Warning state'), - MonitoringStateTrigger::RAISE_CRITICAL => $this->translate('Trigger a Critical state'), - MonitoringStateTrigger::RAISE_UNKNOWN => $this->translate('Trigger an Unknown state'), + MonitoringStateTrigger::IGNORE->value => $this->translate('Do nothing'), + MonitoringStateTrigger::RAISE_WARNING->value => $this->translate('Trigger a Warning state'), + MonitoringStateTrigger::RAISE_CRITICAL->value => $this->translate('Trigger a Critical state'), + MonitoringStateTrigger::RAISE_UNKNOWN->value => $this->translate('Trigger an Unknown state') ]; - $this->addElement('select', $name, [ - 'options' => $selectOptions, - ] + $options); + $this->addElement('select', $name, ['options' => $selectOptions] + $options); } public function hasBeenCreated(): bool { - return $this->result === self::RESULT_CREATED; + return $this->result === ResultStatus::CREATED; } public function hasBeenModified(): bool { - return $this->result === self::RESULT_MODIFIED; + return $this->result === ResultStatus::MODIFIED; } public function hasNotBeenModified(): bool { - return $this->result === self::RESULT_UNMODIFIED; + return $this->result === ResultStatus::UNMODIFIED; } public function hasBeenDeleted(): bool { - return $this->result === self::RESULT_DELETED; + return $this->result === ResultStatus::DELETED; } - protected function onSuccess() + protected function onSuccess(): void { $values = $this->getNormalizedValues(); $settings = new Settings($values); @@ -311,23 +304,17 @@ protected function onSuccess() $set = $this->loadedSet; $set->setSettings($settings); } else { - $set = new MonitoringRuleSet($this->binaryUuid, $this->objectType, $settings); + $set = new MonitoringRuleSet($this->binaryUuid, $this->objectType->value, $settings); } if (empty($values)) { - if ($set->delete($this->db)) { - $result = self::RESULT_DELETED; - } else { - $result = self::RESULT_UNMODIFIED; // No different message for now - } + $this->result = $set->delete($this->db) ? ResultStatus::DELETED : ResultStatus::UNMODIFIED; } else { if ($set->hasBeenLoadedFromDb()) { - $result = $set->store($this->db) ? self::RESULT_MODIFIED : self::RESULT_UNMODIFIED; + $this->result = $set->store($this->db) ? ResultStatus::MODIFIED : ResultStatus::UNMODIFIED; } else { $set->store($this->db); - $result = self::RESULT_CREATED; + $this->result = ResultStatus::CREATED; } } - - $this->result = $result; } } diff --git a/library/Vspheredb/Monitoring/Rule/RuleSetLoader.php b/library/Vspheredb/Monitoring/Rule/RuleSetLoader.php index 1d5170a2..8c01abb6 100644 --- a/library/Vspheredb/Monitoring/Rule/RuleSetLoader.php +++ b/library/Vspheredb/Monitoring/Rule/RuleSetLoader.php @@ -6,11 +6,9 @@ class RuleSetLoader { - /** @var MonitoringRulesTree */ - protected $tree; + protected MonitoringRulesTree $tree; - /** @var Db */ - protected $db; + protected Db $db; public function __construct(MonitoringRulesTree $tree, Db $db) { diff --git a/library/Vspheredb/Monitoring/Rule/RulesTable.php b/library/Vspheredb/Monitoring/Rule/RulesTable.php index 6ec981fa..81b605a8 100644 --- a/library/Vspheredb/Monitoring/Rule/RulesTable.php +++ b/library/Vspheredb/Monitoring/Rule/RulesTable.php @@ -7,7 +7,7 @@ class RulesTable extends Table { /** @var MonitoringRuleSet[] */ - protected $ruleSets; + protected array $ruleSets; /** * @param MonitoringRuleSet[] $ruleSets @@ -17,12 +17,10 @@ public function __construct(array $ruleSets) $this->ruleSets = $ruleSets; } - protected function assemble() + protected function assemble(): void { foreach ($this->ruleSets as $set) { - $this->add(Table::row([ - $set->getDefinition()::getIdentifier() - ])); + $this->add(Table::row([$set->getDefinition()::getIdentifier()])); } } } diff --git a/library/Vspheredb/Monitoring/Rule/Settings.php b/library/Vspheredb/Monitoring/Rule/Settings.php index 7b00dcb0..4de89a1e 100644 --- a/library/Vspheredb/Monitoring/Rule/Settings.php +++ b/library/Vspheredb/Monitoring/Rule/Settings.php @@ -11,6 +11,7 @@ class Settings extends SettingsDataType { public const KEY_SEPARATOR = '/'; + public const KEY_ENABLED = '_enabled'; public function isDisabled(?RuleSet $set = null, ?Rule $rule = null): bool @@ -38,18 +39,20 @@ public function listMainKeys(): array /** * @param string $key + * * @return $this|Settings */ - public function withRemovedKey(string $key) + public function withRemovedKey(string $key): Settings { return $this->withRemovedPrefix($key . Settings::KEY_SEPARATOR); } /** * @param string $prefix + * * @return $this|Settings */ - public function withRemovedPrefix(string $prefix) + public function withRemovedPrefix(string $prefix): Settings { $length = strlen($prefix); $settings = new Settings(); @@ -74,10 +77,9 @@ public static function prefix(?RuleSet $set = null, ?Rule $rule = null, ?UuidInt } $prefix = $set::getIdentifier() . self::KEY_SEPARATOR; if ($rule) { - if ($instance === null) { - $prefix .= $rule::getIdentifier() . self::KEY_SEPARATOR; - } else { - $prefix .= $rule::getIdentifier() . self::KEY_SEPARATOR . $instance->toString() . self::KEY_SEPARATOR; + $prefix .= $rule::getIdentifier() . self::KEY_SEPARATOR; + if ($instance !== null) { + $prefix .= $instance->toString() . self::KEY_SEPARATOR; } } elseif ($instance) { throw new InvalidArgumentException('Rule instance requires a rule'); diff --git a/library/Vspheredb/Monitoring/SingleCheckResult.php b/library/Vspheredb/Monitoring/SingleCheckResult.php index 86b52698..f493cfce 100644 --- a/library/Vspheredb/Monitoring/SingleCheckResult.php +++ b/library/Vspheredb/Monitoring/SingleCheckResult.php @@ -2,13 +2,13 @@ namespace Icinga\Module\Vspheredb\Monitoring; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\CheckPluginState; + class SingleCheckResult implements CheckResultInterface { - /** @var CheckPluginState */ - protected $state; + protected CheckPluginState $state; - /** @var string */ - protected $output; + protected string $output; public function __construct(CheckPluginState $state, string $output) { diff --git a/library/Vspheredb/PathLookup.php b/library/Vspheredb/PathLookup.php index ebee4277..af489a36 100644 --- a/library/Vspheredb/PathLookup.php +++ b/library/Vspheredb/PathLookup.php @@ -6,25 +6,26 @@ use gipfl\ZfDb\Adapter\Adapter; use Icinga\Module\Vspheredb\Db\DbUtil; use Ramsey\Uuid\Uuid; +use Zend_Db_Adapter_Abstract; class PathLookup { - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract|Adapter $db; /** - * @param Adapter|\Zend_Db_Adapter_Abstract $db + * @param Zend_Db_Adapter_Abstract|Adapter $db */ - public function __construct($db) + public function __construct(Zend_Db_Adapter_Abstract|Adapter $db) { $this->db = $db; } /** - * @param $uuid + * @param string $uuid + * * @return string|Link */ - public function linkToObject($uuid) + public function linkToObject(string $uuid): Link|string { if (empty($uuid)) { return '-'; @@ -34,39 +35,31 @@ public function linkToObject($uuid) ->from(['o' => 'object'], ['object_name', 'object_type']) ->where('uuid = ?', DbUtil::quoteBinaryCompat($uuid, $this->db)); - $row = $this->db->fetchRow($query); - if ($row) { + if ($row = $this->db->fetchRow($query)) { return Link::create( $row->object_name, $this->getBaseUrlByType($row->object_type), ['uuid' => Uuid::fromBytes($uuid)->toString()], ['data-base-target' => '_next'] ); - } else { - return '-'; } + + return '-'; } - protected function getBaseUrlByType($type): string + protected function getBaseUrlByType(string $type): string { - switch ($type) { - case 'Datastore': - return 'vspheredb/datastore'; - case 'HostSystem': - return 'vspheredb/host'; - case 'VirtualMachine': - return 'vspheredb/vm'; - case 'ClusterComputeResource': - case 'ComputeResource': - return 'vspheredb/hosts'; - case 'Datacenter': - case 'Folder': - default: - return 'vspheredb/vms'; - } + return match ($type) { + 'Datastore' => 'vspheredb/datastore', + 'HostSystem' => 'vspheredb/host', + 'VirtualMachine' => 'vspheredb/vm', + 'ClusterComputeResource', + 'ComputeResource' => 'vspheredb/hosts', + default => 'vspheredb/vms' + }; } - public function getObjectName($uuid): string + public function getObjectName(string $uuid): string { $query = $this->db->select() ->from(['o' => 'object'], 'object_name') @@ -75,7 +68,7 @@ public function getObjectName($uuid): string return $this->db->fetchOne($query); } - public function getObjectNames($uuids): array + public function getObjectNames(array $uuids): array { if (empty($uuids)) { return []; @@ -89,12 +82,12 @@ public function getObjectNames($uuids): array return $this->db->fetchPairs($query); } - public function listFoldersBelongingTo($uuid): array + public function listFoldersBelongingTo(string $uuid): array { return array_merge($this->listChildFoldersFor($uuid), [$uuid]); } - public function listChildFoldersFor($uuid): array + public function listChildFoldersFor(string $uuid): array { $folders = []; $puuid = $uuid; @@ -108,22 +101,19 @@ public function listChildFoldersFor($uuid): array return $folders; } - protected function fetchChildFolderListFor($uuid): array + protected function fetchChildFolderListFor(string $uuid): array { - $query = $this->db->select()->from('object', 'uuid') + $query = $this->db->select() + ->from('object', 'uuid') ->where('parent_uuid = ?', DbUtil::quoteBinaryCompat($uuid, $this->db)) ->where('object_type NOT IN (?)', ['HostSystem', 'VirtualMachine']); return $this->db->fetchCol($query); } - public function listPathTo($uuid, $includeSelf = true): array + public function listPathTo(string $uuid, bool $includeSelf = true): array { - if ($includeSelf) { - $parents = [$uuid]; - } else { - $parents = []; - } + $parents = $includeSelf ? [$uuid] : []; $puuid = $uuid; while ($puuid = $this->fetchParentForId($puuid)) { @@ -139,11 +129,6 @@ public function fetchParentForId($uuid): ?string ->from('object', 'parent_uuid') ->where('uuid = ?', DbUtil::quoteBinaryCompat($uuid, $this->db)); - $parent = $this->db->fetchOne($query); - if ($parent) { - return $parent; - } else { - return null; - } + return $this->db->fetchOne($query) ?: null; } } diff --git a/library/Vspheredb/PerformanceData/IcingaRrd/RrdImg.php b/library/Vspheredb/PerformanceData/IcingaRrd/RrdImg.php index a72a52e4..86d37b7d 100644 --- a/library/Vspheredb/PerformanceData/IcingaRrd/RrdImg.php +++ b/library/Vspheredb/PerformanceData/IcingaRrd/RrdImg.php @@ -3,7 +3,9 @@ namespace Icinga\Module\Vspheredb\PerformanceData\IcingaRrd; use gipfl\IcingaWeb2\Img; +use ipl\Html\FormattedString; use ipl\Html\Html; +use ipl\Html\HtmlElement; class RrdImg { @@ -19,7 +21,7 @@ class RrdImg protected const COLOR_YELLOW = 'yellow'; // #FFED58 - public static function vmIfTraffic($moref, $device) + public static function vmIfTraffic(string $moref, int $device): HtmlElement { return static::wrapImage(Html::sprintf( mt('vspheredb', 'Throughput (bits/s, %s RX / %s TX)'), @@ -28,7 +30,7 @@ public static function vmIfTraffic($moref, $device) ), $moref, "iface$device", 'vSphereDB-vmIfTraffic'); } - public static function vmIfPackets($moref, $device) + public static function vmIfPackets(string $moref, int $device): HtmlElement { return static::wrapImage(Html::sprintf( mt('vspheredb', 'Packets (%s / %s Unicast, %s BCast, %s MCast, %s Dropped)'), @@ -40,7 +42,7 @@ public static function vmIfPackets($moref, $device) ), $moref, "iface$device", 'vSphereDB-vmIfPackets'); } - public static function vmDiskSeeks($moref, $device) + public static function vmDiskSeeks(string $moref, string $device): HtmlElement { return static::wrapImage(Html::sprintf( mt('vspheredb', 'Disk Seeks: %s small / %s medium / %s large'), @@ -50,7 +52,7 @@ public static function vmDiskSeeks($moref, $device) ), $moref, "disk$device", 'vSphereDB-vmDiskSeeks'); } - public static function vmDiskReadWrites($moref, $device) + public static function vmDiskReadWrites(string $moref, string $device): HtmlElement { return static::wrapImage(Html::sprintf( mt('vspheredb', 'Average Number %s Reads / %s Writes'), @@ -59,7 +61,7 @@ public static function vmDiskReadWrites($moref, $device) ), $moref, "disk$device", 'vSphereDB-vmDiskReadWrites'); } - public static function vmDiskTotalLatency($moref, $device) + public static function vmDiskTotalLatency(string $moref, string $device): HtmlElement { return static::wrapImage(Html::sprintf( mt('vspheredb', 'Latency %s Read / %s Write'), @@ -68,38 +70,41 @@ public static function vmDiskTotalLatency($moref, $device) ), $moref, "disk$device", 'vSphereDB-vmDiskTotalLatency'); } - protected static function prepareImg($moref, $device, $template) + protected static function prepareImg(string $moref, string $device, string $template): Img { // Disk was 300x140, Net 340x180 $width = 340; $height = 180; - $end = \floor(\time() / 300) * 300; - $start = $end - 86400; + $end = floor(time() / 300) * 300; $start = $end - 14400; $params = [ - 'file' => \sprintf('%s/%s.rrd', $moref, $device), + 'file' => sprintf('%s/%s.rrd', $moref, $device), 'height' => $height, 'width' => $width, 'rnd' => floor(time() / 20), 'format' => 'png', 'start' => $start, - 'end' => $end, + 'end' => $end ]; return Img::create('rrd/img', $params + ['template' => $template], ['class' => 'rrd-image']); } - protected static function colorLegend($color) + protected static function colorLegend(string $color): HtmlElement { return Html::tag('div', ['class' => 'color-square color-' . $color]); } - protected static function wrapImage($title, $moref, $device, $template) - { + protected static function wrapImage( + FormattedString $title, + string $moref, + string $device, + string $template + ): HtmlElement { // TODO, CSS. disk was 1em, net 2em return Html::tag('div', ['class' => 'rrd-image-legend'], [ Html::tag('strong', $title), - static::prepareImg($moref, $device, $template), + static::prepareImg($moref, $device, $template) ]); } } diff --git a/library/Vspheredb/PerformanceData/InfluxConnectionForVcenterLoader.php b/library/Vspheredb/PerformanceData/InfluxConnectionForVcenterLoader.php index de73e3b5..8ba4dd59 100644 --- a/library/Vspheredb/PerformanceData/InfluxConnectionForVcenterLoader.php +++ b/library/Vspheredb/PerformanceData/InfluxConnectionForVcenterLoader.php @@ -41,33 +41,28 @@ public static function load(VCenter $vCenter, CurlAsync $curl, LoopInterface $lo PerfdataConsumer::create((array) $row), $loop ); - switch ($instance->getSetting('api_version')) { - case 'v1': - $influxDb = resolve(new InfluxDbConnectionV1( - $curl, - $instance->getSetting('base_url'), - $instance->getSetting('username'), - $instance->getSetting('password') - )); - break; - case 'v2': - $influxDb = resolve(new InfluxDbConnectionV2( - $curl, - $instance->getSetting('base_url'), - $instance->getSetting('username'), - $instance->getSetting('password') - // $instance->getSetting('organization'), - // $instance->getSetting('token') - )); - break; - default: - $influxDb = InfluxDbConnectionFactory::create( - $curl, - $instance->getSetting('base_url'), - $instance->getSetting('username'), - $instance->getSetting('password') - ); - } + $influxDb = match ($instance->getSetting('api_version')) { + 'v1' => resolve(new InfluxDbConnectionV1( + $curl, + $instance->getSetting('base_url'), + $instance->getSetting('username'), + $instance->getSetting('password') + )), + 'v2' => resolve(new InfluxDbConnectionV2( + $curl, + $instance->getSetting('base_url'), + $instance->getSetting('username'), + $instance->getSetting('password') + // $instance->getSetting('organization'), + // $instance->getSetting('token') + )), + default => InfluxDbConnectionFactory::create( + $curl, + $instance->getSetting('base_url'), + $instance->getSetting('username'), + $instance->getSetting('password') + ), + }; return $influxDb->then(function (InfluxDbConnection $influxDb) use ($vCenterSettings, $loop) { $influxDbWriter = new ChunkedInfluxDbWriter( diff --git a/library/Vspheredb/PerformanceData/MetricCSVToInfluxDataPoint.php b/library/Vspheredb/PerformanceData/MetricCSVToInfluxDataPoint.php index 0832f2a7..167e7b3d 100644 --- a/library/Vspheredb/PerformanceData/MetricCSVToInfluxDataPoint.php +++ b/library/Vspheredb/PerformanceData/MetricCSVToInfluxDataPoint.php @@ -29,31 +29,21 @@ public static function map( foreach ($metric->value as $series) { $key = static::makeKey($object, $series->id); $metric = $countersMap[$series->id->counterId]; - foreach ( - array_combine( - $dates, - explode(',', $series->value) - ) as $time => $value - ) { + foreach (array_combine($dates, explode(',', $series->value)) as $time => $value) { $result[$time][$key][$metric] = $value === '' ? null : (int) $value; } } foreach ($result as $time => $results) { foreach ($results as $key => $metrics) { if (! isset($tags[$key])) { - if (count($tags) > 10) { - $tagList = implode(', ', array_slice(array_keys($tags), 0, 10)) . ', ...'; - } else { - $tagList = implode(', ', array_keys($tags)); - } + $tagList = count($tags) > 10 + ? implode(', ', array_slice(array_keys($tags), 0, 10)) . ', ...' + : implode(', ', array_keys($tags)); + throw new InvalidArgumentException("Cannot find tags for '$key', got: $tagList"); } - yield new DataPoint( - $measurementName, - ['instance' => $key] + $tags[$key], - $metrics, - $time - ); + + yield new DataPoint($measurementName, ['instance' => $key] + $tags[$key], $metrics, $time); } } } diff --git a/library/Vspheredb/Polling/ApiConnection.php b/library/Vspheredb/Polling/ApiConnection.php index d910a934..e0570166 100644 --- a/library/Vspheredb/Polling/ApiConnection.php +++ b/library/Vspheredb/Polling/ApiConnection.php @@ -20,48 +20,47 @@ class ApiConnection implements EventEmitterInterface use EventEmitterTrait; use StateMachine; + // Events public const ON_READY = 'ready'; + public const ON_ERROR = 'error'; + // States public const STATE_STOPPED = 'stopped'; + public const STATE_STOPPING = 'stopping'; + public const STATE_INIT = 'initializing'; + public const STATE_LOGIN = 'login'; + public const STATE_CONNECTED = 'connected'; + public const STATE_FAILING = 'failing'; - /** @var CurlAsync */ - protected $curl; + protected CurlAsync $curl; - /** @var LoopInterface */ - protected $loop; + protected ?LoopInterface $loop = null; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - protected $scheduledPollerStartup; + protected ?TimerInterface $scheduledPollerStartup = null; - /** @var ServerInfo */ - protected $serverInfo; + protected ServerInfo $serverInfo; - protected $wsdlFile; + protected ?string $wsdlFile = null; - /** @var VsphereApi */ - protected $api; + protected ?VsphereApi $api = null; - protected $stopping; + protected ?bool $stopping = null; - /** @var PromiseInterface */ - protected $loginPromise; + protected ?PromiseInterface $loginPromise = null; - /** @var PromiseInterface */ - protected $wsdlPromise; + protected ?PromiseInterface $wsdlPromise = null; - /** @var TimerInterface */ - protected $sessionChecker; + protected ?TimerInterface $sessionChecker = null; - /** @var ?string */ - protected $lastErrorMessage = null; + protected ?string $lastErrorMessage = null; public function __construct(CurlAsync $curl, ServerInfo $serverInfo, LoggerInterface $logger) { @@ -88,18 +87,14 @@ public function __construct(CurlAsync $curl, ServerInfo $serverInfo, LoggerInter }); $this->onTransition(self::STATE_INIT, self::STATE_STOPPING, function () { $this->stopping = true; - if ($this->wsdlPromise) { - $this->wsdlPromise->cancel(); - $this->wsdlPromise = null; - } + $this->wsdlPromise?->cancel(); + $this->wsdlPromise = null; $this->setState(self::STATE_STOPPED); }); $this->onTransition(self::STATE_LOGIN, self::STATE_STOPPING, function () { $this->stopping = true; - if ($this->loginPromise) { - $this->loginPromise->cancel(); - $this->loginPromise = null; - } + $this->loginPromise?->cancel(); + $this->loginPromise = null; $this->setState(self::STATE_STOPPED); }); // TODO: do we need failing -> stopping? @@ -130,13 +125,13 @@ public function __construct(CurlAsync $curl, ServerInfo $serverInfo, LoggerInter }); } - protected function stopSessionChecker() + protected function stopSessionChecker(): void { $this->loop->cancelTimer($this->sessionChecker); $this->sessionChecker = null; } - protected function runSessionChecker() + protected function runSessionChecker(): void { $this->sessionChecker = $this->loop->addPeriodicTimer(150, function () { $this->getApi()->eventuallyLogin()->then(null, function (Exception $e) { @@ -148,22 +143,22 @@ protected function runSessionChecker() }); } - public function getApi() + public function getApi(): ?VsphereApi { return $this->api; } - public function isReady() + public function isReady(): bool { return $this->getState() === self::STATE_CONNECTED; } - public function getServerInfo() + public function getServerInfo(): ServerInfo { return $this->serverInfo; } - protected function scheduleNextAttempt($delay = 60) + protected function scheduleNextAttempt($delay = 60): void { if ($this->scheduledPollerStartup) { return; @@ -174,7 +169,7 @@ protected function scheduleNextAttempt($delay = 60) }); } - protected function eventuallyRemoveScheduledAttempt() + protected function eventuallyRemoveScheduledAttempt(): void { if ($this->scheduledPollerStartup) { $this->loop->cancelTimer($this->scheduledPollerStartup); @@ -182,7 +177,7 @@ protected function eventuallyRemoveScheduledAttempt() } } - protected function startWsdlDownload() + protected function startWsdlDownload(): void { $this->wsdlPromise = $this->fetchWsdl() ->then(function ($wsdlFile) { @@ -199,13 +194,13 @@ protected function startWsdlDownload() }); } - protected function eventuallyLogout() + protected function eventuallyLogout(): PromiseInterface { $api = new VsphereApi($this->wsdlFile, $this->serverInfo, $this->curl, $this->loop, $this->logger); return $api->eventuallyLogout(); } - protected function login() + protected function login(): PromiseInterface { $api = new VsphereApi($this->wsdlFile, $this->serverInfo, $this->curl, $this->loop, $this->logger); return $this->loginPromise = $api->eventuallyLogin()->then(function (UserSession $session) use ($api) { @@ -223,22 +218,23 @@ protected function login() }); } - public function stop() + public function stop(): void { $this->setState(self::STATE_STOPPING); } - public function run(LoopInterface $loop) + public function run(LoopInterface $loop): void { $this->loop = $loop; $this->setState(self::STATE_INIT); } - public function fetchWsdl() + public function fetchWsdl(): PromiseInterface { $serverId = $this->serverInfo->getServerId(); $cacheDir = SafeCacheDir::getSubDirectory("wsdl-$serverId"); $loader = new WsdlLoader($cacheDir, $this->logger, $this->serverInfo, $this->curl); + return $loader->fetchInitialWsdlFile($this->loop); } @@ -247,7 +243,7 @@ public function getLastErrorMessage(): ?string return $this->lastErrorMessage; } - protected function logError($message) + protected function logError($message): void { $this->lastErrorMessage = $message; $this->logger->error($message); diff --git a/library/Vspheredb/Polling/ApiConnectionHandler.php b/library/Vspheredb/Polling/ApiConnectionHandler.php index 675fb867..102794ab 100644 --- a/library/Vspheredb/Polling/ApiConnectionHandler.php +++ b/library/Vspheredb/Polling/ApiConnectionHandler.php @@ -21,42 +21,39 @@ class ApiConnectionHandler implements EventEmitterInterface use EventEmitterTrait; public const ON_INITIALIZED_SERVER = 'initialized'; + public const ON_CONNECT = 'connection'; + public const ON_DISCONNECT = 'disconnect'; + protected const TIMEOUT_ON_FAILURE = 60; - /** @var CurlAsync */ - protected $curl; + protected CurlAsync $curl; - /** @var LoggerInterface */ - protected $parentLogger; + protected LoggerInterface $parentLogger; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var ?LoopInterface */ - protected $loop; + protected ?LoopInterface $loop = null; - /** @var ServerSet */ - protected $servers; + protected ServerSet $servers; /** @var ApiConnection[] $vcenterId => ApiConnection */ - protected $apiConnections = []; + protected array $apiConnections = []; /** @var array> [vcenterId => [serverId => ServerInfo, ...] */ - protected $vCenterCandidates = []; + protected array $vCenterCandidates = []; /** @var array [serverId => Deferred] */ - protected $initializations = []; + protected array $initializations = []; /** @var array key is the serverId */ - protected $failing = []; + protected array $failing = []; /** @var array key is the serverId */ - protected $failingErrorMessages = []; + protected array $failingErrorMessages = []; - /** @var ServerSet */ - protected $appliedServers; + protected ServerSet $appliedServers; public function __construct(CurlAsync $curl, LoggerInterface $logger) { @@ -66,7 +63,7 @@ public function __construct(CurlAsync $curl, LoggerInterface $logger) $this->appliedServers = $this->servers = new ServerSet(); } - public function setServerSet(ServerSet $servers) + public function setServerSet(ServerSet $servers): void { if (!$servers->equals($this->servers)) { $this->servers = $servers; @@ -111,10 +108,11 @@ public function getApiConnectionOverview(): array return $connections; } - protected function applyServers(ServerSet $servers) + protected function applyServers(ServerSet $servers): void { if ($servers->equals($this->appliedServers)) { $this->logger->debug('Server Set is unchanged'); + return; } $vCenterCandidates = []; @@ -142,7 +140,7 @@ protected function applyServers(ServerSet $servers) $this->removeObsoleteFailingServers(); } - protected function startInitialization(ServerInfo $server) + protected function startInitialization(ServerInfo $server): void { $serverId = $server->getServerId(); $this->initializations[$serverId] = $initialize = $this->initialize($server); @@ -180,25 +178,20 @@ protected function initialize(ServerInfo $server): Deferred }); }); $apiConnection->on(ApiConnection::ON_ERROR, function (ApiConnection $connection) use ($server, $deferred) { + $message = 'Initialization failed'; if ($error = $connection->getLastErrorMessage()) { - $message = "Initialization failed: $error"; - } else { - $message = 'Initialization failed'; + $message .= ": $error"; } $deferred->reject(new Exception($message)); $this->setFailed($server, $message); }); - $this->logger->notice(sprintf( - 'initializing server %d: %s', - $server->getServerId(), - $server->getIdentifier() - )); + $this->logger->notice(sprintf('initializing server %d: %s', $server->getServerId(), $server->getIdentifier())); $apiConnection->run($this->loop); return $deferred; } - protected function launchNewlyConfiguredVCenters() + protected function launchNewlyConfiguredVCenters(): void { foreach ($this->vCenterCandidates as $vCenterId => $servers) { /** @var ServerInfo $server */ @@ -241,7 +234,7 @@ protected function launchNewlyConfiguredVCenters() } } - protected function setFailed(ServerInfo $server, ?string $message = 'unknown error') + protected function setFailed(ServerInfo $server, ?string $message = 'unknown error'): void { $serverId = $server->getServerId(); $this->logger->warning(sprintf( @@ -259,6 +252,7 @@ protected function setFailed(ServerInfo $server, ?string $message = 'unknown err 'Not retrying %s, connection has been removed', $server->getIdentifier() )); + return; } $this->loop->cancelTimer($this->failing[$serverId]); @@ -292,7 +286,7 @@ protected function listAppliedServers(): array return $list; } - protected function removeObsoleteFailingServers() + protected function removeObsoleteFailingServers(): void { $serverMap = $this->listAppliedServers(); foreach ($this->failing as $serverId => $timer) { @@ -305,7 +299,7 @@ protected function removeObsoleteFailingServers() } } - protected function removeUnConfiguredApiConnections() + protected function removeUnConfiguredApiConnections(): void { $remove = []; foreach ($this->apiConnections as $vCenterId => $connection) { @@ -331,13 +325,13 @@ protected function createApiConnection(ServerInfo $server): ApiConnection return new ApiConnection($this->curl, $server, $this->parentLogger); } - public function run(LoopInterface $loop) + public function run(LoopInterface $loop): void { $this->loop = $loop; $this->applyServers($this->servers); } - public function stop() + public function stop(): void { $this->logger->notice('Stopping API connection handler'); $this->applyServers($this->servers = new ServerSet()); diff --git a/library/Vspheredb/Polling/CookieStore.php b/library/Vspheredb/Polling/CookieStore.php index 00256368..2a5ffa69 100644 --- a/library/Vspheredb/Polling/CookieStore.php +++ b/library/Vspheredb/Polling/CookieStore.php @@ -12,19 +12,15 @@ class CookieStore { - /** @var string */ - private $cacheDir; + private string $cacheDir; - /** @var string */ - private $cookieFile; + private string $cookieFile; - /** @var array */ - private $cookies = []; + private array $cookies = []; - /** @var LoggerInterface */ - private $logger; + private LoggerInterface $logger; - public function __construct($cacheDir, ServerInfo $serverInfo, LoggerInterface $logger) + public function __construct(string $cacheDir, ServerInfo $serverInfo, LoggerInterface $logger) { $this->cacheDir = $cacheDir; $this->logger = $logger; @@ -37,12 +33,12 @@ public function __construct($cacheDir, ServerInfo $serverInfo, LoggerInterface $ /** * @return bool */ - public function hasCookies() + public function hasCookies(): bool { - return !empty($this->cookies); + return ! empty($this->cookies); } - public function setCookies(array $cookies) + public function setCookies(array $cookies): void { if ($cookies !== $this->cookies) { $this->logger->notice('Cookies changed, storing new ones'); @@ -54,7 +50,7 @@ public function setCookies(array $cookies) /** * Discard our Cookie */ - public function forgetCookies() + public function forgetCookies(): void { $this->cookies = []; if (file_exists($this->cookieFile)) { @@ -62,7 +58,7 @@ public function forgetCookies() } } - public function getCookies() + public function getCookies(): false|array { if (file_exists($this->cookieFile . '.fake')) { return file($this->cookieFile . '.fake', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); diff --git a/library/Vspheredb/Polling/CurlOptions.php b/library/Vspheredb/Polling/CurlOptions.php index 39f0cb63..0b9f4f1a 100644 --- a/library/Vspheredb/Polling/CurlOptions.php +++ b/library/Vspheredb/Polling/CurlOptions.php @@ -16,31 +16,14 @@ class CurlOptions /** @var array */ public const PROXY_TYPES = [ 'HTTP' => CURLPROXY_HTTP, - 'SOCKS5' => CURLPROXY_SOCKS5, + 'SOCKS5' => CURLPROXY_SOCKS5 ]; - public static function forServerInfo(ServerInfo $server) + public static function forServerInfo(ServerInfo $server): array { $host = $server->get('host'); - if (preg_match('/^(.+?):(\d{1,5})$/', $host, $match)) { - $host = $match[1]; - $port = (int) $match[2]; - } else { - $port = null; - } - $options = [ - CURLOPT_HTTPHEADER => [ - // Host header disabled for now, see #496 - // "Host: $host", - 'Expect:', - 'User-Agent: Icinga-vSphereDB/1.8', - ] - ]; - - // Unused, we're authenticating via SOAP - // if (null !== ($username = $server->get('username'))) { - // $options[CURLOPT_USERPWD] = sprintf('%s:%s', $username, $server->get('password')); - // } + $port = preg_match('/^(.+?):(\d{1,5})$/', $host, $match) ? (int) $match[2] : null; + $options[CURLOPT_HTTPHEADER] = ['Expect:', 'User-Agent: Icinga-vSphereDB/1.8']; if ($proxyType = $server->get('proxy_type')) { // TODO: Depending on the PHP and Curl version, we might want to support HTTPS proxies @@ -70,7 +53,7 @@ public static function forServerInfo(ServerInfo $server) return $options; } - protected static function wantCurlProxyType($type) + protected static function wantCurlProxyType(int|string $type): int { if (is_int($type)) { if (in_array($type, self::PROXY_TYPES, true)) { diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/CounterLookup.php b/library/Vspheredb/Polling/PerformanceCounterLookup/CounterLookup.php index 23083a8b..ca270d57 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/CounterLookup.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/CounterLookup.php @@ -7,16 +7,18 @@ interface CounterLookup { /** - * @param UuidInterface $vCenterUuid + * @param ?UuidInterface $vCenterUuid + * * @return array */ - public function fetchTags(?UuidInterface $vCenterUuid = null); + public function fetchTags(?UuidInterface $vCenterUuid = null): array; /** * Hint: instance = '*' -> all instances, instance = '' -> aggregated * - * @param UuidInterface $vCenterUuid + * @param ?UuidInterface $vCenterUuid + * * @return array */ - public function fetchRequiredMetricInstances(?UuidInterface $vCenterUuid = null); + public function fetchRequiredMetricInstances(?UuidInterface $vCenterUuid = null): array; } diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/CounterMap.php b/library/Vspheredb/Polling/PerformanceCounterLookup/CounterMap.php index a7349729..fe472467 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/CounterMap.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/CounterMap.php @@ -4,16 +4,20 @@ use Icinga\Module\Vspheredb\Polling\PerformanceSet\PerformanceSet; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Adapter_Abstract; abstract class CounterMap { - public static function fetchCounters($db, PerformanceSet $set, UuidInterface $vCenterUuid) - { + public static function fetchCounters( + Zend_Db_Adapter_Abstract $db, + PerformanceSet $set, + UuidInterface $vCenterUuid + ): array { $query = $db ->select() ->from('performance_counter', [ 'v' => 'counter_key', - 'k' => 'name', + 'k' => 'name' ]) ->where('vcenter_uuid = ?', $vCenterUuid->getBytes()) ->where('group_name = ?', $set->getCountersGroup()) diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/DefaultCounterLookup.php b/library/Vspheredb/Polling/PerformanceCounterLookup/DefaultCounterLookup.php index 5f154d2e..813468ad 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/DefaultCounterLookup.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/DefaultCounterLookup.php @@ -2,30 +2,32 @@ namespace Icinga\Module\Vspheredb\Polling\PerformanceCounterLookup; -use gipfl\ZfDb\Adapter\Adapter; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use RuntimeException; +use Zend_Db_Adapter_Abstract; +use Zend_Db_Select; abstract class DefaultCounterLookup implements CounterLookup { /** - * @var Adapter|\Zend_Db_Adapter_Abstract + * @var Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; - protected $tagColumns; + /** @var ?string[] */ + protected ?array $tagColumns = null; - protected $objectKey; + protected ?string $objectKey = null; - protected $instanceKey; + protected ?string $instanceKey = null; - protected $staticInstanceKey; + protected ?string $staticInstanceKey = null; /** - * @param Adapter|\Zend_Db_Adapter_Abstract $db + * @param Zend_Db_Adapter_Abstract $db */ - public function __construct($db) + public function __construct(Zend_Db_Adapter_Abstract $db) { $this->db = $db; } @@ -65,27 +67,21 @@ public function fetchRequiredMetricInstances(?UuidInterface $vCenterUuid = null) { if ($this->hasInstanceKey()) { return static::explodeInstances($this->db->fetchPairs($this->prepareInstancesQuery($vCenterUuid))); - } else { - return $this->db->fetchPairs($this->prepareInstancesQuery($vCenterUuid)); } + + return $this->db->fetchPairs($this->prepareInstancesQuery($vCenterUuid)); } - abstract protected function prepareBaseQuery(UuidInterface $vCenterUuid); + abstract protected function prepareBaseQuery(UuidInterface $vCenterUuid): Zend_Db_Select; - abstract protected function prepareInstancesQuery(UuidInterface $vCenterUuid); + abstract protected function prepareInstancesQuery(UuidInterface $vCenterUuid): Zend_Db_Select; protected static function explodeInstances($queryResult): array { - $result = []; - - foreach ($queryResult as $key => $value) { - $result[$key] = explode(',', $value); - } - - return $result; + return array_map(fn ($value) => explode(',', $value), $queryResult); } - protected function getTagColumns() + protected function getTagColumns(): array { if ($this->tagColumns === null) { throw $this->missingPropertyError('tagColumns'); @@ -94,7 +90,7 @@ protected function getTagColumns() return $this->tagColumns; } - protected function getObjectKey() + protected function getObjectKey(): string { if ($this->objectKey === null) { throw $this->missingPropertyError('objectKey'); @@ -103,7 +99,7 @@ protected function getObjectKey() return $this->objectKey; } - protected function getInstanceKey() + protected function getInstanceKey(): string { if ($this->instanceKey === null) { throw $this->missingPropertyError('instanceKey'); @@ -112,10 +108,10 @@ protected function getInstanceKey() return $this->instanceKey; } - protected function convertResultRowUuidsToText($row) + protected function convertResultRowUuidsToText($row): void { foreach (array_keys((array) $row) as $key) { - if ($key === 'uuid' || substr($key, -5) === '_uuid') { + if ($key === 'uuid' || str_ends_with($key, '_uuid')) { if (strlen($row->$key) === 16) { $row->$key = Uuid::fromBytes($row->$key)->toString(); } diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/HostCounterLookup.php b/library/Vspheredb/Polling/PerformanceCounterLookup/HostCounterLookup.php index 6261f01c..c9e2a3df 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/HostCounterLookup.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/HostCounterLookup.php @@ -3,28 +3,29 @@ namespace Icinga\Module\Vspheredb\Polling\PerformanceCounterLookup; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Select; class HostCounterLookup extends DefaultCounterLookup { - protected $objectKey = 'host_moref'; + protected ?string $objectKey = 'host_moref'; - protected $tagColumns = [ + protected ?array $tagColumns = [ 'host_uuid' => 'o.uuid', 'sysinfo_uuid' => 'hs.sysinfo_uuid', 'host_moref' => 'o.moref', - 'host_name' => 'o.object_name', + 'host_name' => 'o.object_name' ]; - protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null) + protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { return $this->prepareBaseQuery($vCenterUuid) ->columns([ 'o.moref', - 'nix' => '(NULL)', + 'nix' => '(NULL)' ]); } - protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null) + protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { $query = $this->db->select()->from(['o' => 'object'], []) ->join(['hs' => 'host_system'], 'o.uuid = hs.uuid', []) diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/HostNetworkCounterLookup.php b/library/Vspheredb/Polling/PerformanceCounterLookup/HostNetworkCounterLookup.php index 45daf78a..7f5ea355 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/HostNetworkCounterLookup.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/HostNetworkCounterLookup.php @@ -3,34 +3,36 @@ namespace Icinga\Module\Vspheredb\Polling\PerformanceCounterLookup; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Select; class HostNetworkCounterLookup extends DefaultCounterLookup { - protected $objectKey = 'host_moref'; - protected $instanceKey = 'device_label'; + protected ?string $objectKey = 'host_moref'; - protected $tagColumns = [ + protected ?string $instanceKey = 'device_label'; + + protected ?array $tagColumns = [ 'host_uuid' => 'o.uuid', 'sysinfo_uuid' => 'hs.sysinfo_uuid', 'host_moref' => 'o.moref', 'host_name' => 'o.object_name', // 'pnic_key' => 'hpn.nic_key', -> key-vim.host.PhysicalNic-vmnic0, ugly - 'device_label' => 'hpn.device', + 'device_label' => 'hpn.device' ]; - protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null) + protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { return $this->prepareBaseQuery($vCenterUuid) ->columns([ 'o.moref', - 'device' => "GROUP_CONCAT(hpn.device SEPARATOR ',')", + 'device' => "GROUP_CONCAT(hpn.device SEPARATOR ',')" ]) ->group('hs.uuid') ->order('hs.uuid') ->order('hpn.device'); } - protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null) + protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { $query = $this->db->select()->from(['o' => 'object'], []) ->join(['hs' => 'host_system'], 'o.uuid = hs.uuid', []) diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/VmCounterLookup.php b/library/Vspheredb/Polling/PerformanceCounterLookup/VmCounterLookup.php index 1f8d73a4..1e6fd7df 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/VmCounterLookup.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/VmCounterLookup.php @@ -3,28 +3,29 @@ namespace Icinga\Module\Vspheredb\Polling\PerformanceCounterLookup; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Select; class VmCounterLookup extends DefaultCounterLookup { - protected $objectKey = 'vm_moref'; + protected ?string $objectKey = 'vm_moref'; - protected $tagColumns = [ + protected ?array $tagColumns = [ 'vm_uuid' => 'o.uuid', 'vm_name' => 'o.object_name', 'vm_guest_host_name' => 'vm.guest_host_name', - 'vm_moref' => 'o.moref', + 'vm_moref' => 'o.moref' ]; - protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null) + protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { return $this->prepareBaseQuery($vCenterUuid) ->columns([ 'o.moref', - 'nix' => '(NULL)', + 'nix' => '(NULL)' ]); } - protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null) + protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { $query = $this->db->select()->from(['o' => 'object'], []) ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []) diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/VmDiskCounterLookup.php b/library/Vspheredb/Polling/PerformanceCounterLookup/VmDiskCounterLookup.php index 878a5c7b..0c5e1e1a 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/VmDiskCounterLookup.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/VmDiskCounterLookup.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Vspheredb\Polling\PerformanceCounterLookup; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Select; class VmDiskCounterLookup extends DefaultCounterLookup { @@ -12,28 +13,30 @@ class VmDiskCounterLookup extends DefaultCounterLookup . " ELSE 'scsi' END" . " || vmhc.bus_number || ':' || vmhw.unit_number"; - protected $objectKey = 'vm_moref'; - protected $instanceKey = 'disk_hardware_key'; - protected $tagColumns = [ + protected ?string $objectKey = 'vm_moref'; + + protected ?string $instanceKey = 'disk_hardware_key'; + + protected ?array $tagColumns = [ 'vm_uuid' => 'o.uuid', 'vm_name' => 'o.object_name', 'vm_guest_host_name' => 'vm.guest_host_name', 'vm_moref' => 'o.moref', 'disk_hardware_key' => '(' . self::INSTANCE_KEY_EXPRESSION . ')', - 'disk_hardware_label' => 'vmhw.label', + 'disk_hardware_label' => 'vmhw.label' ]; - protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null) + protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { return $this->prepareBaseQuery($vCenterUuid) ->columns([ 'o.moref', - 'GROUP_CONCAT(' . self::INSTANCE_KEY_EXPRESSION . " SEPARATOR ',')", + 'GROUP_CONCAT(' . self::INSTANCE_KEY_EXPRESSION . " SEPARATOR ',')" ]) ->group('vm.uuid'); } - protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null) + protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { $query = $this->db->select()->from(['o' => 'object'], []) ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []) diff --git a/library/Vspheredb/Polling/PerformanceCounterLookup/VmNetworkCounterLookup.php b/library/Vspheredb/Polling/PerformanceCounterLookup/VmNetworkCounterLookup.php index a36b3a16..ebe54940 100644 --- a/library/Vspheredb/Polling/PerformanceCounterLookup/VmNetworkCounterLookup.php +++ b/library/Vspheredb/Polling/PerformanceCounterLookup/VmNetworkCounterLookup.php @@ -3,12 +3,15 @@ namespace Icinga\Module\Vspheredb\Polling\PerformanceCounterLookup; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Select; class VmNetworkCounterLookup extends DefaultCounterLookup { - protected $objectKey = 'vm_moref'; - protected $instanceKey = 'interface_hardware_key'; - protected $tagColumns = [ + protected ?string $objectKey = 'vm_moref'; + + protected ?string $instanceKey = 'interface_hardware_key'; + + protected ?array $tagColumns = [ 'vm_uuid' => 'o.uuid', 'vm_moref' => 'o.moref', 'vm_name' => 'o.object_name', @@ -16,22 +19,22 @@ class VmNetworkCounterLookup extends DefaultCounterLookup 'interface_hardware_key' => 'vna.hardware_key', // 'parent_name' => 'po.object_name', 'interface_label' => 'vh.label', - // 'portgroup_name' => 'pgo.object_name', + // 'portgroup_name' => 'pgo.object_name' ]; - protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null) + protected function prepareInstancesQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { return $this->prepareBaseQuery($vCenterUuid) ->columns([ 'o.moref', - 'hardware_key' => "GROUP_CONCAT(vna.hardware_key SEPARATOR ',')", + 'hardware_key' => "GROUP_CONCAT(vna.hardware_key SEPARATOR ',')" ]) ->group('vm.uuid') ->order('vm.runtime_host_uuid') ->order('vna.hardware_key'); } - protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null) + protected function prepareBaseQuery(?UuidInterface $vCenterUuid = null): Zend_Db_Select { $query = $this->db->select()->from(['o' => 'object'], []) ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []) diff --git a/library/Vspheredb/Polling/PerformanceQuerySpecHelper.php b/library/Vspheredb/Polling/PerformanceQuerySpecHelper.php index cc85ac7b..0f924847 100644 --- a/library/Vspheredb/Polling/PerformanceQuerySpecHelper.php +++ b/library/Vspheredb/Polling/PerformanceQuerySpecHelper.php @@ -11,19 +11,20 @@ abstract class PerformanceQuerySpecHelper { /** * @param string $objectType 'HostSystem', 'VirtualMachine'... - * @param array $counters [counterKey => name, ...] - * @param $objectWithInstances [vm-123 => [scsi0:0, ...], ...]. To test: * would be all instances + * @param array $counters [counterKey => name, ...] + * @param array $objectWithInstances [vm-123 => [scsi0:0, ...], ...]. To test: * would be all instances * @param int $count Defaults to 180. We have 1h in a 20s interval. 3600 / 20 = 180 * @param int $interval Defaults to 20s, "realtime" + * * @return PerfQuerySpec[] */ public static function prepareQuerySpec( - $objectType, - $counters, - $objectWithInstances, - $count = 180, - $interval = 20 - ) { + string $objectType, + array $counters, + array $objectWithInstances, + int $count = 180, + int $interval = 20 + ): array { $duration = $interval * ($count); $now = floor(time() / $interval) * $interval; $start = Util::makeDateTime($now - $duration); diff --git a/library/Vspheredb/Polling/PerformanceSet/DatastoreDiskPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/DatastoreDiskPerformanceSet.php index e00ccfd7..a00483c1 100644 --- a/library/Vspheredb/Polling/PerformanceSet/DatastoreDiskPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/DatastoreDiskPerformanceSet.php @@ -4,13 +4,16 @@ class DatastoreDiskPerformanceSet extends DefaultPerformanceSet { - protected $name = 'DatastoreDisk'; - protected $objectType = 'Datastore'; - protected $countersGroup = 'disk'; - protected $counters = [ + protected ?string $name = 'DatastoreDisk'; + + protected ?string $objectType = 'Datastore'; + + protected ?string $countersGroup = 'disk'; + + protected ?array $counters = [ 'capacity', 'used', 'provisioned', - 'deltaused', + 'deltaused' ]; } diff --git a/library/Vspheredb/Polling/PerformanceSet/DatastorePerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/DatastorePerformanceSet.php index f86bc95f..5f9ee8b7 100644 --- a/library/Vspheredb/Polling/PerformanceSet/DatastorePerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/DatastorePerformanceSet.php @@ -4,10 +4,13 @@ class DatastorePerformanceSet extends DefaultPerformanceSet { - protected $name = 'Datastore'; - protected $objectType = 'Datastore'; - protected $countersGroup = 'datastore'; - protected $counters = [ + protected ?string $name = 'Datastore'; + + protected ?string $objectType = 'Datastore'; + + protected ?string $countersGroup = 'datastore'; + + protected ?array $counters = [ 'read', 'write', 'datastoreReadBytes', @@ -15,6 +18,6 @@ class DatastorePerformanceSet extends DefaultPerformanceSet 'datastoreReadIops', 'datastoreWriteIops', 'totalReadLatency', - 'totalWriteLatency', + 'totalWriteLatency' ]; } diff --git a/library/Vspheredb/Polling/PerformanceSet/DefaultPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/DefaultPerformanceSet.php index efeb5972..39430627 100644 --- a/library/Vspheredb/Polling/PerformanceSet/DefaultPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/DefaultPerformanceSet.php @@ -6,19 +6,19 @@ abstract class DefaultPerformanceSet implements PerformanceSet { - /** @var string Name for this Performance Set */ - protected $name; + /** @var ?string Name for this Performance Set */ + protected ?string $name = null; - /** @var string vmWare Object Type */ - protected $objectType; + /** @var ?string vmWare Object Type */ + protected ?string $objectType = null; - /** @var string vmWare Counters Group */ - protected $countersGroup; + /** @var ?string vmWare Counters Group */ + protected ?string $countersGroup = null; - /** @var string[] Required counters by name */ - protected $counters; + /** @var ?string[] Required counters by name */ + protected ?array $counters = null; - public function getName() + public function getName(): string { if ($this->name === null) { throw $this->missingPropertyError('name'); @@ -27,7 +27,7 @@ public function getName() return $this->name; } - public function getObjectType() + public function getObjectType(): string { if ($this->objectType === null) { throw $this->missingPropertyError('objectType'); @@ -36,7 +36,7 @@ public function getObjectType() return $this->objectType; } - public function getCountersGroup() + public function getCountersGroup(): string { if ($this->countersGroup === null) { throw $this->missingPropertyError('countersGroup'); @@ -45,7 +45,7 @@ public function getCountersGroup() return $this->countersGroup; } - public function getCounters() + public function getCounters(): array { if ($this->counters === null) { throw $this->missingPropertyError('counters'); @@ -56,9 +56,10 @@ public function getCounters() /** * @param $property + * * @return RuntimeException */ - protected function missingPropertyError($property) + protected function missingPropertyError($property): RuntimeException { return new RuntimeException(sprintf( '$%s is required when extending %s, missing in %s', diff --git a/library/Vspheredb/Polling/PerformanceSet/HostCpuPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/HostCpuPerformanceSet.php index f4708a03..768f3967 100644 --- a/library/Vspheredb/Polling/PerformanceSet/HostCpuPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/HostCpuPerformanceSet.php @@ -4,16 +4,19 @@ class HostCpuPerformanceSet extends DefaultPerformanceSet { - protected $name = 'HostCpu'; - protected $objectType = 'HostSystem'; - protected $countersGroup = 'cpu'; - protected $counters = [ + protected ?string $name = 'HostCpu'; + + protected ?string $objectType = 'HostSystem'; + + protected ?string $countersGroup = 'cpu'; + + protected ?array $counters = [ 'coreUtilization', 'demand', 'latency', 'readiness', 'usage', 'usagemhz', - 'utilization', + 'utilization' ]; } diff --git a/library/Vspheredb/Polling/PerformanceSet/HostMemoryPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/HostMemoryPerformanceSet.php index bfa9877a..b310f857 100644 --- a/library/Vspheredb/Polling/PerformanceSet/HostMemoryPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/HostMemoryPerformanceSet.php @@ -4,10 +4,13 @@ class HostMemoryPerformanceSet extends DefaultPerformanceSet { - protected $name = 'HostMemory'; - protected $objectType = 'HostSystem'; - protected $countersGroup = 'mem'; - protected $counters = [ + protected ?string $name = 'HostMemory'; + + protected ?string $objectType = 'HostSystem'; + + protected ?string $countersGroup = 'mem'; + + protected ?array $counters = [ 'active', 'usage', 'totalCapacity', @@ -16,6 +19,6 @@ class HostMemoryPerformanceSet extends DefaultPerformanceSet 'swapout', 'swapinRate', 'swapoutRate', - 'vmmemctl', + 'vmmemctl' ]; } diff --git a/library/Vspheredb/Polling/PerformanceSet/HostNetworkPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/HostNetworkPerformanceSet.php index 4709dfd6..0c50fd3a 100644 --- a/library/Vspheredb/Polling/PerformanceSet/HostNetworkPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/HostNetworkPerformanceSet.php @@ -4,10 +4,13 @@ class HostNetworkPerformanceSet extends DefaultPerformanceSet { - protected $name = 'HostNetworkAdapter'; - protected $objectType = 'HostSystem'; - protected $countersGroup = 'net'; - protected $counters = [ + protected ?string $name = 'HostNetworkAdapter'; + + protected ?string $objectType = 'HostSystem'; + + protected ?string $countersGroup = 'net'; + + protected ?array $counters = [ // averaged alternative: received, transmitted, usage // TODO: evaluate net.usage 'bytesRx', @@ -21,6 +24,6 @@ class HostNetworkPerformanceSet extends DefaultPerformanceSet 'droppedRx', 'droppedTx', 'errorsRx', - 'errorsTx', + 'errorsTx' ]; } diff --git a/library/Vspheredb/Polling/PerformanceSet/PerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/PerformanceSet.php index ff5f3d9b..94810144 100644 --- a/library/Vspheredb/Polling/PerformanceSet/PerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/PerformanceSet.php @@ -7,20 +7,20 @@ interface PerformanceSet /** * @return string */ - public function getName(); + public function getName(): string; /** * @return string */ - public function getObjectType(); + public function getObjectType(): string; /** * @return string */ - public function getCountersGroup(); + public function getCountersGroup(): string; /** * @return string[] */ - public function getCounters(); + public function getCounters(): array; } diff --git a/library/Vspheredb/Polling/PerformanceSet/VmCpuPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/VmCpuPerformanceSet.php index 6c4bf8ce..9460b163 100644 --- a/library/Vspheredb/Polling/PerformanceSet/VmCpuPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/VmCpuPerformanceSet.php @@ -4,16 +4,19 @@ class VmCpuPerformanceSet extends DefaultPerformanceSet { - protected $name = 'VmCpu'; - protected $objectType = 'VirtualMachine'; - protected $countersGroup = 'cpu'; - protected $counters = [ + protected ?string $name = 'VmCpu'; + + protected ?string $objectType = 'VirtualMachine'; + + protected ?string $countersGroup = 'cpu'; + + protected ?array $counters = [ 'coreUtilization', 'demand', 'latency', 'readiness', 'usage', 'usagemhz', - 'utilization', + 'utilization' ]; } diff --git a/library/Vspheredb/Polling/PerformanceSet/VmDiskPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/VmDiskPerformanceSet.php index dda0a9f5..01e7f008 100644 --- a/library/Vspheredb/Polling/PerformanceSet/VmDiskPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/VmDiskPerformanceSet.php @@ -4,10 +4,13 @@ class VmDiskPerformanceSet extends DefaultPerformanceSet { - protected $name = 'VirtualDisk'; - protected $objectType = 'VirtualMachine'; - protected $countersGroup = 'virtualDisk'; - protected $counters = [ + protected ?string $name = 'VirtualDisk'; + + protected ?string $objectType = 'VirtualMachine'; + + protected ?string $countersGroup = 'virtualDisk'; + + protected ?array $counters = [ // 'busResets', -> not per instance // 'commandsAborted', -> not per instance 'numberReadAveraged', // rate, average diff --git a/library/Vspheredb/Polling/PerformanceSet/VmMemoryPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/VmMemoryPerformanceSet.php index 543731ed..9130d697 100644 --- a/library/Vspheredb/Polling/PerformanceSet/VmMemoryPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/VmMemoryPerformanceSet.php @@ -4,10 +4,13 @@ class VmMemoryPerformanceSet extends DefaultPerformanceSet { - protected $name = 'VmMemory'; - protected $objectType = 'VirtualMachine'; - protected $countersGroup = 'mem'; - protected $counters = [ + protected ?string $name = 'VmMemory'; + + protected ?string $objectType = 'VirtualMachine'; + + protected ?string $countersGroup = 'mem'; + + protected ?array $counters = [ 'active', 'usage', 'granted', @@ -16,6 +19,6 @@ class VmMemoryPerformanceSet extends DefaultPerformanceSet 'swapout', 'swapinRate', 'swapoutRate', - 'vmmemctl', + 'vmmemctl' ]; } diff --git a/library/Vspheredb/Polling/PerformanceSet/VmNetworkPerformanceSet.php b/library/Vspheredb/Polling/PerformanceSet/VmNetworkPerformanceSet.php index 65bff24f..102ddaa0 100644 --- a/library/Vspheredb/Polling/PerformanceSet/VmNetworkPerformanceSet.php +++ b/library/Vspheredb/Polling/PerformanceSet/VmNetworkPerformanceSet.php @@ -4,10 +4,13 @@ class VmNetworkPerformanceSet extends DefaultPerformanceSet { - protected $name = 'VirtualNetworkAdapter'; - protected $objectType = 'VirtualMachine'; - protected $countersGroup = 'net'; - protected $counters = [ + protected ?string $name = 'VirtualNetworkAdapter'; + + protected ?string $objectType = 'VirtualMachine'; + + protected ?string $countersGroup = 'net'; + + protected ?array $counters = [ 'bytesRx', // rate / average / kiloBytesPerSecond 'bytesTx', 'packetsRx', @@ -17,6 +20,6 @@ class VmNetworkPerformanceSet extends DefaultPerformanceSet 'multicastRx', 'multicastTx', 'droppedRx', - 'droppedTx', + 'droppedTx' ]; } diff --git a/library/Vspheredb/Polling/PropertySet/ComputeResourcePropertySet.php b/library/Vspheredb/Polling/PropertySet/ComputeResourcePropertySet.php index 4fd300b2..229eb4a1 100644 --- a/library/Vspheredb/Polling/PropertySet/ComputeResourcePropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/ComputeResourcePropertySet.php @@ -6,7 +6,7 @@ class ComputeResourcePropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('ComputeResource', [ @@ -18,7 +18,7 @@ public static function create() 'summary.numHosts', // 'summary.overallStatus', 'summary.totalCpu', - 'summary.totalMemory', + 'summary.totalMemory' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/DatastorePropertySet.php b/library/Vspheredb/Polling/PropertySet/DatastorePropertySet.php index c53e15fc..de05ea71 100644 --- a/library/Vspheredb/Polling/PropertySet/DatastorePropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/DatastorePropertySet.php @@ -6,7 +6,7 @@ class DatastorePropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('Datastore', [ diff --git a/library/Vspheredb/Polling/PropertySet/FullObjectListPropertySet.php b/library/Vspheredb/Polling/PropertySet/FullObjectListPropertySet.php index 1769f9de..f6a4067e 100644 --- a/library/Vspheredb/Polling/PropertySet/FullObjectListPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/FullObjectListPropertySet.php @@ -6,7 +6,7 @@ class FullObjectListPropertySet implements PropertySet { - public static function create() + public static function create(): array { return static::propertySet([ 'Datacenter', @@ -21,16 +21,17 @@ public static function create() 'VirtualApp', 'Network', 'DistributedVirtualSwitch', - 'DistributedVirtualPortgroup', + 'DistributedVirtualPortgroup' ], ['name', 'parent', 'overallStatus', 'tag']); } /** * @param string[] $types * @param ?string[] $pathSet + * * @return PropertySpec[] */ - public static function propertySet(array $types, ?array $pathSet = null) + public static function propertySet(array $types, ?array $pathSet = null): array { $propSet = []; foreach ($types as $type) { diff --git a/library/Vspheredb/Polling/PropertySet/HostHardwarePropertySet.php b/library/Vspheredb/Polling/PropertySet/HostHardwarePropertySet.php index 44701390..4c2c4c59 100644 --- a/library/Vspheredb/Polling/PropertySet/HostHardwarePropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostHardwarePropertySet.php @@ -6,11 +6,11 @@ class HostHardwarePropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ - 'hardware.pciDevice', + 'hardware.pciDevice' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/HostHbaPropertySet.php b/library/Vspheredb/Polling/PropertySet/HostHbaPropertySet.php index d2fcc731..e7c915a1 100644 --- a/library/Vspheredb/Polling/PropertySet/HostHbaPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostHbaPropertySet.php @@ -6,11 +6,11 @@ class HostHbaPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ - 'config.storageDevice.hostBusAdapter', + 'config.storageDevice.hostBusAdapter' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/HostNetworkPropertySet.php b/library/Vspheredb/Polling/PropertySet/HostNetworkPropertySet.php index 39f10850..d42d56e7 100644 --- a/library/Vspheredb/Polling/PropertySet/HostNetworkPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostNetworkPropertySet.php @@ -6,11 +6,11 @@ class HostNetworkPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ - 'config.network', + 'config.network' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/HostPhysicalNicPropertySet.php b/library/Vspheredb/Polling/PropertySet/HostPhysicalNicPropertySet.php index 4e99d514..04818cdb 100644 --- a/library/Vspheredb/Polling/PropertySet/HostPhysicalNicPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostPhysicalNicPropertySet.php @@ -6,11 +6,11 @@ class HostPhysicalNicPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ - 'config.network.pnic', + 'config.network.pnic' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/HostQuickStatsPropertySet.php b/library/Vspheredb/Polling/PropertySet/HostQuickStatsPropertySet.php index 8149e59c..8d3553b2 100644 --- a/library/Vspheredb/Polling/PropertySet/HostQuickStatsPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostQuickStatsPropertySet.php @@ -6,7 +6,7 @@ class HostQuickStatsPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ @@ -14,7 +14,7 @@ public static function create() 'summary.quickStats.distributedMemoryFairness', 'summary.quickStats.overallCpuUsage', 'summary.quickStats.overallMemoryUsage', - 'summary.quickStats.uptime', + 'summary.quickStats.uptime' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/HostSensorsPropertySet.php b/library/Vspheredb/Polling/PropertySet/HostSensorsPropertySet.php index c6f28aa4..aabff90b 100644 --- a/library/Vspheredb/Polling/PropertySet/HostSensorsPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostSensorsPropertySet.php @@ -6,11 +6,11 @@ class HostSensorsPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ - 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', + 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/HostSystemPropertySet.php b/library/Vspheredb/Polling/PropertySet/HostSystemPropertySet.php index 3cef9b46..e0454f1d 100644 --- a/library/Vspheredb/Polling/PropertySet/HostSystemPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostSystemPropertySet.php @@ -6,7 +6,7 @@ class HostSystemPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ @@ -35,7 +35,7 @@ public static function create() 'summary.hardware.memorySize', 'hardware.biosInfo.releaseDate', - 'summary.hardware.otherIdentifyingInfo', + 'summary.hardware.otherIdentifyingInfo' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/HostVirtualNicPropertySet.php b/library/Vspheredb/Polling/PropertySet/HostVirtualNicPropertySet.php index 6252504c..f2589d41 100644 --- a/library/Vspheredb/Polling/PropertySet/HostVirtualNicPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/HostVirtualNicPropertySet.php @@ -6,11 +6,11 @@ class HostVirtualNicPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('HostSystem', [ - 'config.network.vnic', + 'config.network.vnic' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/PropertySet.php b/library/Vspheredb/Polling/PropertySet/PropertySet.php index 608f491e..7303416c 100644 --- a/library/Vspheredb/Polling/PropertySet/PropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/PropertySet.php @@ -9,5 +9,5 @@ interface PropertySet /** * @return PropertySpec[] */ - public static function create(); + public static function create(): array; } diff --git a/library/Vspheredb/Polling/PropertySet/StoragePodPropertySet.php b/library/Vspheredb/Polling/PropertySet/StoragePodPropertySet.php index c2b3947e..5ffe98ba 100644 --- a/library/Vspheredb/Polling/PropertySet/StoragePodPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/StoragePodPropertySet.php @@ -6,13 +6,13 @@ class StoragePodPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('StoragePod', [ 'name', 'summary.capacity', - 'summary.freeSpace', + 'summary.freeSpace' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/VirtualMachinePropertySet.php b/library/Vspheredb/Polling/PropertySet/VirtualMachinePropertySet.php index 74197445..0b452a7f 100644 --- a/library/Vspheredb/Polling/PropertySet/VirtualMachinePropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/VirtualMachinePropertySet.php @@ -6,7 +6,7 @@ class VirtualMachinePropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('VirtualMachine', [ @@ -44,7 +44,7 @@ public static function create() 'config.cpuHotAddEnabled', 'config.memoryHotAddEnabled', // 'runtime.bootTime', - // 'runtime.suspendTime', + // 'runtime.suspendTime' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/VmDatastoreUsagePropertySet.php b/library/Vspheredb/Polling/PropertySet/VmDatastoreUsagePropertySet.php index 4de130b2..2c16a595 100644 --- a/library/Vspheredb/Polling/PropertySet/VmDatastoreUsagePropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/VmDatastoreUsagePropertySet.php @@ -6,7 +6,7 @@ class VmDatastoreUsagePropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('VirtualMachine', [ diff --git a/library/Vspheredb/Polling/PropertySet/VmDiskUsagePropertySet.php b/library/Vspheredb/Polling/PropertySet/VmDiskUsagePropertySet.php index f0f9ab9a..b73cc2ab 100644 --- a/library/Vspheredb/Polling/PropertySet/VmDiskUsagePropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/VmDiskUsagePropertySet.php @@ -6,11 +6,11 @@ class VmDiskUsagePropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('VirtualMachine', [ - 'guest.disk', + 'guest.disk' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/VmHardwarePropertySet.php b/library/Vspheredb/Polling/PropertySet/VmHardwarePropertySet.php index 6790a8be..4f3ee94c 100644 --- a/library/Vspheredb/Polling/PropertySet/VmHardwarePropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/VmHardwarePropertySet.php @@ -6,11 +6,11 @@ class VmHardwarePropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('VirtualMachine', [ - 'config.hardware', + 'config.hardware' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/VmQuickStatsPropertySet.php b/library/Vspheredb/Polling/PropertySet/VmQuickStatsPropertySet.php index 343f52a7..eca9263a 100644 --- a/library/Vspheredb/Polling/PropertySet/VmQuickStatsPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/VmQuickStatsPropertySet.php @@ -6,7 +6,7 @@ class VmQuickStatsPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('VirtualMachine', [ @@ -29,7 +29,7 @@ public static function create() 'summary.quickStats.staticCpuEntitlement', 'summary.quickStats.staticMemoryEntitlement', 'summary.quickStats.swappedMemory', - 'summary.quickStats.uptimeSeconds', + 'summary.quickStats.uptimeSeconds' ]) ]; } diff --git a/library/Vspheredb/Polling/PropertySet/VmSnapshotPropertySet.php b/library/Vspheredb/Polling/PropertySet/VmSnapshotPropertySet.php index 2b588815..f22433d3 100644 --- a/library/Vspheredb/Polling/PropertySet/VmSnapshotPropertySet.php +++ b/library/Vspheredb/Polling/PropertySet/VmSnapshotPropertySet.php @@ -6,11 +6,11 @@ class VmSnapshotPropertySet implements PropertySet { - public static function create() + public static function create(): array { return [ PropertySpec::create('VirtualMachine', [ - 'snapshot', + 'snapshot' ]) ]; } diff --git a/library/Vspheredb/Polling/RestApi.php b/library/Vspheredb/Polling/RestApi.php index 84fa0771..d8f71bf5 100644 --- a/library/Vspheredb/Polling/RestApi.php +++ b/library/Vspheredb/Polling/RestApi.php @@ -23,27 +23,18 @@ class RestApi { - /** @var CurlAsync */ - protected $curl; + protected CurlAsync $curl; - /** @var CookieStore */ - protected $sidStore; + protected CookieStore $sidStore; - /** @var ServerInfo */ - protected $server; + protected ServerInfo $server; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; /** @var array[] */ - protected $curlOptions; - /** - * @var VCenter - */ - protected $vCenter; + protected array $curlOptions; - /** @var \Closure Will become obsolete with PHP 8.1 */ - private $normalizeBatchResult; + protected VCenter $vCenter; public function __construct( ServerInfo $server, @@ -57,10 +48,6 @@ public function __construct( $this->curl = $curl; $this->logger = $logger; $this->curlOptions = CurlOptions::forServerInfo($server); - $this->normalizeBatchResult = function ($result) { - // print_r($result); - return $this->normalizeBatchResult($result); - }; } /** @@ -169,11 +156,11 @@ function (ResponseInterface $result) { // "user":"username@VSPHERE.LOCAL" // } return true; - } else { - $this->logger->debug('REST API Session is no longer valid'); - $this->sidStore->forgetCookies(); - return false; } + $this->logger->debug('REST API Session is no longer valid'); + $this->sidStore->forgetCookies(); + + return false; } ); } @@ -188,7 +175,7 @@ protected function authenticate(): PromiseInterface { $request = new Request('POST', $this->apiUrl('session'), [ 'Accept' => 'application/json', - 'Authorization' => $this->generateBasicAuthHeaderLine(), + 'Authorization' => $this->generateBasicAuthHeaderLine() ]); return $this->curl->send($request, $this->curlOptions) @@ -264,7 +251,7 @@ protected function send(RequestInterface $request): PromiseInterface return $this->curl->send($request, $this->curlOptions); } - public function getUsedCategories() + public function getUsedCategories(): PromiseInterface { // Test only, doesn't work return $this->post("cis/tagging/category?action=list-used-categories"); @@ -279,40 +266,36 @@ protected function taggingBatch(string $action, $body = null): PromiseInterface protected function get(string $url): PromiseInterface { return $this->send($this->request('GET', $this->apiUrl($url))) - ->then([$this, 'decodeResponse']); + ->then($this->decodeResponse(...)); } protected function post(string $url, $body = null): PromiseInterface { return $this->send($this->request('POST', $this->apiUrl($url), $body)) - ->then([$this, 'decodeResponse']); + ->then($this->decodeResponse(...)); } protected function taggingBatchLegacy(string $action, $body = null): PromiseInterface { return $this->postLegacy("cis/tagging/batch?~action=$action", $body) - ->then($this->normalizeBatchResult); + ->then($this->normalizeBatchResult(...)); } protected function getLegacy(string $url): PromiseInterface { return $this->send($this->request('GET', $this->legacyUrl($url))) - ->then([$this, 'decodeResponse']) - ->then([$this, 'requireValueProperty']); + ->then($this->decodeResponse(...)) + ->then($this->requireValueProperty(...)); } protected function postLegacy(string $url, $body = null): PromiseInterface { return $this->send($this->request('POST', $this->legacyUrl($url), $body)) - ->then([$this, 'decodeResponse']) - ->then([$this, 'requireValueProperty']); + ->then($this->decodeResponse(...)) + ->then($this->requireValueProperty(...)); } - /** - * Will become protected, once we have ->decodeResponse(...) on 8.1 - * @internal - */ - public function decodeResponse(ResponseInterface $response) + protected function decodeResponse(ResponseInterface $response) { if ($response->getStatusCode() > 299) { throw new RuntimeException( @@ -336,23 +319,18 @@ protected function legacyUrl(?string $path = null): string protected function addSessionIdToRequest(RequestInterface $request): RequestInterface { - if ($this->sidStore && $this->sidStore->hasCookies()) { + if ($this->sidStore->hasCookies()) { foreach ($this->sidStore->getCookies() as $sid) { - if (str_starts_with($request->getUri()->getPath(), '/rest/')) { - $request = $request->withAddedHeader('cookie', "vmware-api-session-id=$sid"); - } else { - $request = $request->withAddedHeader('vmware-api-session-id', $sid); - } + $request = str_starts_with($request->getUri()->getPath(), '/rest/') + ? $request->withAddedHeader('cookie', "vmware-api-session-id=$sid") + : $request->withAddedHeader('vmware-api-session-id', $sid); } } return $request; } - /** - * @internal Will become protected with 8.1 - */ - public function requireValueProperty(stdClass $result) + protected function requireValueProperty(stdClass $result) { if (isset($result->error_type)) { // { @@ -377,7 +355,7 @@ public function requireValueProperty(stdClass $result) protected function request(string $method, string $url, $body = null): RequestInterface { $headers = [ - 'Accept' => 'application/json', + 'Accept' => 'application/json' ]; if ($body) { $headers['Content-type'] = 'application/json'; diff --git a/library/Vspheredb/Polling/SelectSet/ComputeResourceSelectSet.php b/library/Vspheredb/Polling/SelectSet/ComputeResourceSelectSet.php index 1d8121a5..bc1ef201 100644 --- a/library/Vspheredb/Polling/SelectSet/ComputeResourceSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/ComputeResourceSelectSet.php @@ -4,13 +4,13 @@ class ComputeResourceSelectSet implements SelectSet { - public static function create() + public static function create(): array { return [ GenericSpec::traverseFolder([ GenericSpec::TRAVERSE_DC_HOST_SYSTEMS ]), - GenericSpec::traverseDatacenterHosts(), + GenericSpec::traverseDatacenterHosts() ]; } } diff --git a/library/Vspheredb/Polling/SelectSet/DatastoreSelectSet.php b/library/Vspheredb/Polling/SelectSet/DatastoreSelectSet.php index 58a715d1..a88989c5 100644 --- a/library/Vspheredb/Polling/SelectSet/DatastoreSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/DatastoreSelectSet.php @@ -6,15 +6,15 @@ class DatastoreSelectSet implements SelectSet { public const TRAVERSE_STORAGE_POD = 'TraverseStoragePod'; - public static function create() + public static function create(): array { return [ GenericSpec::traverseFolder([ GenericSpec::TRAVERSE_DC_DATA_STORES, - self::TRAVERSE_STORAGE_POD, + self::TRAVERSE_STORAGE_POD ]), GenericSpec::traverseDatacenterDataStores(), - GenericSpec::traverse(self::TRAVERSE_STORAGE_POD, 'StoragePod', 'childEntity'), + GenericSpec::traverse(self::TRAVERSE_STORAGE_POD, 'StoragePod', 'childEntity') ]; } } diff --git a/library/Vspheredb/Polling/SelectSet/DistributedVirtualPortgroupSelectSet.php b/library/Vspheredb/Polling/SelectSet/DistributedVirtualPortgroupSelectSet.php index fb6043ba..481e0239 100644 --- a/library/Vspheredb/Polling/SelectSet/DistributedVirtualPortgroupSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/DistributedVirtualPortgroupSelectSet.php @@ -4,13 +4,13 @@ class DistributedVirtualPortgroupSelectSet implements SelectSet { - public static function create() + public static function create(): array { return [ GenericSpec::traverseFolder([ GenericSpec::TRAVERSE_DC_NETWORKS ]), - GenericSpec::traverseDatacenterNetworks(), + GenericSpec::traverseDatacenterNetworks() ]; } } diff --git a/library/Vspheredb/Polling/SelectSet/DistributedVirtualSwitchSelectSet.php b/library/Vspheredb/Polling/SelectSet/DistributedVirtualSwitchSelectSet.php index bf60e522..3e1b11af 100644 --- a/library/Vspheredb/Polling/SelectSet/DistributedVirtualSwitchSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/DistributedVirtualSwitchSelectSet.php @@ -4,13 +4,13 @@ class DistributedVirtualSwitchSelectSet implements SelectSet { - public static function create() + public static function create(): array { return [ GenericSpec::traverseFolder([ GenericSpec::TRAVERSE_DC_NETWORKS ]), - GenericSpec::traverseDatacenterNetworks(), + GenericSpec::traverseDatacenterNetworks() ]; } } diff --git a/library/Vspheredb/Polling/SelectSet/FullSelectSet.php b/library/Vspheredb/Polling/SelectSet/FullSelectSet.php index 3fd24abc..dd0f7853 100644 --- a/library/Vspheredb/Polling/SelectSet/FullSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/FullSelectSet.php @@ -15,7 +15,7 @@ class FullSelectSet implements SelectSet /** * @return SelectionSpec[] */ - public static function create() + public static function create(): array { return [ GenericSpec::traverseDatacenterHosts(), @@ -29,7 +29,7 @@ public static function create() GenericSpec::TRAVERSE_DC_VIRTUAL_MACHINES, self::TRAVERSE_CR1, self::TRAVERSE_CR2, - self::TRAVERSE_STORAGE_POD, + self::TRAVERSE_STORAGE_POD ]), GenericSpec::traverse(self::TRAVERSE_STORAGE_POD, 'StoragePod', 'childEntity'), GenericSpec::traverse(self::TRAVERSE_CR1, 'ComputeResource', 'resourcePool', [ @@ -39,7 +39,7 @@ public static function create() // TraverseCR1 needs an array of two SelectionSpec objects, named // TraverseRP1 and TraverseRP2 SelectionSpec::reference(self::TRAVERSE_RP1), - SelectionSpec::reference(self::TRAVERSE_RP2), + SelectionSpec::reference(self::TRAVERSE_RP2) ]), // TraverseCR2 can lead only to a HostSystem object, so there is no // need for it to have a selectSet array @@ -49,9 +49,9 @@ public static function create() // two paths out of ResourcePool, so it needs an array of two // SelectionSpec objects, named TraverseRP1 and TraverseRP2 SelectionSpec::reference(self::TRAVERSE_RP1), - SelectionSpec::reference(self::TRAVERSE_RP2), + SelectionSpec::reference(self::TRAVERSE_RP2) ]), - GenericSpec::traverse(self::TRAVERSE_RP2, 'ResourcePool', 'vm'), + GenericSpec::traverse(self::TRAVERSE_RP2, 'ResourcePool', 'vm') ]; } } diff --git a/library/Vspheredb/Polling/SelectSet/GenericSpec.php b/library/Vspheredb/Polling/SelectSet/GenericSpec.php index 67db6f1c..adeaef07 100644 --- a/library/Vspheredb/Polling/SelectSet/GenericSpec.php +++ b/library/Vspheredb/Polling/SelectSet/GenericSpec.php @@ -15,9 +15,10 @@ abstract class GenericSpec /** * @param string[] $specReferences + * * @return TraversalSpec */ - public static function traverseFolder(array $specReferences = []) + public static function traverseFolder(array $specReferences = []): TraversalSpec { return self::traverse(self::TRAVERSE_FOLDER, 'Folder', 'childEntity', array_merge([ self::TRAVERSE_FOLDER @@ -28,31 +29,32 @@ public static function traverseFolder(array $specReferences = []) * @param string $name * @param string $type * @param string $path + * * @return TraversalSpec */ - public static function traverseDatacenter($name, $type, $path) + public static function traverseDatacenter(string $name, string $type, string $path): TraversalSpec { return self::traverse($name, $type, $path, [ self::TRAVERSE_FOLDER ]); } - public static function traverseDatacenterHosts() + public static function traverseDatacenterHosts(): TraversalSpec { return self::traverseDatacenter(self::TRAVERSE_DC_HOST_SYSTEMS, 'Datacenter', 'hostFolder'); } - public static function traverseDatacenterVirtualMachines() + public static function traverseDatacenterVirtualMachines(): TraversalSpec { return self::traverseDatacenter(self::TRAVERSE_DC_VIRTUAL_MACHINES, 'Datacenter', 'vmFolder'); } - public static function traverseDatacenterDataStores() + public static function traverseDatacenterDataStores(): TraversalSpec { return self::traverseDatacenter(self::TRAVERSE_DC_DATA_STORES, 'Datacenter', 'datastoreFolder'); } - public static function traverseDatacenterNetworks() + public static function traverseDatacenterNetworks(): TraversalSpec { return self::traverseDatacenter(self::TRAVERSE_DC_NETWORKS, 'Datacenter', 'networkFolder'); } @@ -62,10 +64,15 @@ public static function traverseDatacenterNetworks() * @param string $type * @param string $path * @param ?SelectionSpec[]|string[] $selectionSet + * * @return TraversalSpec */ - public static function traverse($name, $type, $path, ?array $selectionSet = null) - { + public static function traverse( + string $name, + string $type, + string $path, + ?array $selectionSet = null + ): TraversalSpec { if ($selectionSet) { foreach ($selectionSet as $key => $entry) { if (is_string($entry)) { diff --git a/library/Vspheredb/Polling/SelectSet/HostSystemSelectSet.php b/library/Vspheredb/Polling/SelectSet/HostSystemSelectSet.php index 6d9d1f33..df64ed5f 100644 --- a/library/Vspheredb/Polling/SelectSet/HostSystemSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/HostSystemSelectSet.php @@ -11,15 +11,15 @@ class HostSystemSelectSet implements SelectSet /** * @return TraversalSpec[] */ - public static function create() + public static function create(): array { return [ GenericSpec::traverseFolder([ GenericSpec::TRAVERSE_DC_HOST_SYSTEMS, - self::TRAVERSE_COMPUTE_RESOURCES, + self::TRAVERSE_COMPUTE_RESOURCES ]), GenericSpec::traverseDatacenterHosts(), - GenericSpec::traverse(self::TRAVERSE_COMPUTE_RESOURCES, 'ComputeResource', 'host'), + GenericSpec::traverse(self::TRAVERSE_COMPUTE_RESOURCES, 'ComputeResource', 'host') ]; } } diff --git a/library/Vspheredb/Polling/SelectSet/SelectSet.php b/library/Vspheredb/Polling/SelectSet/SelectSet.php index 8c8f8d33..30a16a8d 100644 --- a/library/Vspheredb/Polling/SelectSet/SelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/SelectSet.php @@ -9,5 +9,5 @@ interface SelectSet /** * @return SelectionSpec[] */ - public static function create(); + public static function create(): array; } diff --git a/library/Vspheredb/Polling/SelectSet/StoragePodSelectSet.php b/library/Vspheredb/Polling/SelectSet/StoragePodSelectSet.php index f5854ce1..90349bdc 100644 --- a/library/Vspheredb/Polling/SelectSet/StoragePodSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/StoragePodSelectSet.php @@ -4,13 +4,13 @@ class StoragePodSelectSet implements SelectSet { - public static function create() + public static function create(): array { return [ GenericSpec::traverseFolder([ - GenericSpec::TRAVERSE_DC_DATA_STORES, + GenericSpec::TRAVERSE_DC_DATA_STORES ]), - GenericSpec::traverseDatacenterDataStores(), + GenericSpec::traverseDatacenterDataStores() ]; } } diff --git a/library/Vspheredb/Polling/SelectSet/VirtualMachineSelectSet.php b/library/Vspheredb/Polling/SelectSet/VirtualMachineSelectSet.php index e05b3bd6..6c04c46d 100644 --- a/library/Vspheredb/Polling/SelectSet/VirtualMachineSelectSet.php +++ b/library/Vspheredb/Polling/SelectSet/VirtualMachineSelectSet.php @@ -6,15 +6,15 @@ class VirtualMachineSelectSet implements SelectSet { public const TRAVERSE_VIRTUAL_APP = 'TraverseVirtualApp'; - public static function create() + public static function create(): array { return [ GenericSpec::traverseFolder([ self::TRAVERSE_VIRTUAL_APP, - GenericSpec::TRAVERSE_DC_VIRTUAL_MACHINES, + GenericSpec::TRAVERSE_DC_VIRTUAL_MACHINES ]), GenericSpec::traverseDatacenterVirtualMachines(), - GenericSpec::traverse(self::TRAVERSE_VIRTUAL_APP, 'VirtualApp', 'vm'), + GenericSpec::traverse(self::TRAVERSE_VIRTUAL_APP, 'VirtualApp', 'vm') ]; } } diff --git a/library/Vspheredb/Polling/ServerInfo.php b/library/Vspheredb/Polling/ServerInfo.php index f438829f..24d284b7 100644 --- a/library/Vspheredb/Polling/ServerInfo.php +++ b/library/Vspheredb/Polling/ServerInfo.php @@ -6,16 +6,17 @@ use gipfl\Json\JsonString; use Icinga\Module\Vspheredb\DbObject\VCenterServer; use InvalidArgumentException; +use stdClass; use function array_key_exists; class ServerInfo implements JsonSerialization { - /** @var array */ - protected $properties; + protected array $properties; /** * ServerInfo constructor. + * * @param array $properties */ public function __construct(array $properties) @@ -45,6 +46,7 @@ public static function fromSerialization($object): ServerInfo /** * @param VCenterServer $server + * * @return static */ public static function fromServer(VCenterServer $server): ServerInfo @@ -61,28 +63,25 @@ public function isEnabled(): bool * @param string $key * @param null $default * - * @return mixed|null + * @return ?mixed */ public function get(string $key, $default = null): mixed { if (array_key_exists($key, $this->properties)) { - if ($this->properties[$key] === null) { - return $default; - } else { - return $this->properties[$key]; - } + return $this->properties[$key] === null ? $default : $this->properties[$key]; } throw new InvalidArgumentException("Trying to access invalid property: '$key'"); } - public function jsonSerialize(): \stdClass + public function jsonSerialize(): stdClass { ksort($this->properties); + return (object) $this->properties; } - public function getUrl() + public function getUrl(): string { return sprintf( '%s://%s', diff --git a/library/Vspheredb/Polling/ServerSet.php b/library/Vspheredb/Polling/ServerSet.php index 1fd23efa..3cd3084d 100644 --- a/library/Vspheredb/Polling/ServerSet.php +++ b/library/Vspheredb/Polling/ServerSet.php @@ -8,7 +8,7 @@ class ServerSet implements JsonSerialization { /** @var array */ - protected $servers = []; + protected array $servers = []; /** * ServerSet constructor. @@ -37,7 +37,7 @@ public function listServerIds(): array return array_keys($this->servers); } - public function addServer(ServerInfo $server) + public function addServer(ServerInfo $server): void { $this->servers[$server->getServerId()] = $server; ksort($this->servers); @@ -58,6 +58,7 @@ public function getServers(): array /** * @param VCenterServer[] $servers + * * @return static */ public static function fromServers(array $servers): ServerSet diff --git a/library/Vspheredb/Polling/SyncStore/HostHardwareSyncStore.php b/library/Vspheredb/Polling/SyncStore/HostHardwareSyncStore.php index f50e85f9..a3debeed 100644 --- a/library/Vspheredb/Polling/SyncStore/HostHardwareSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/HostHardwareSyncStore.php @@ -4,8 +4,11 @@ class HostHardwareSyncStore extends HostPropertyInstancesSyncStore { - protected $baseKey = 'hardware.pciDevice'; - protected $keyProperty = 'id'; - protected $dbKeyProperty = 'id'; - protected $instanceClass = 'HostPciDevice'; + protected string $baseKey = 'hardware.pciDevice'; + + protected string $keyProperty = 'id'; + + protected string $dbKeyProperty = 'id'; + + protected string $instanceClass = 'HostPciDevice'; } diff --git a/library/Vspheredb/Polling/SyncStore/HostHbaSyncStore.php b/library/Vspheredb/Polling/SyncStore/HostHbaSyncStore.php index 023dbf48..f3a92e13 100644 --- a/library/Vspheredb/Polling/SyncStore/HostHbaSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/HostHbaSyncStore.php @@ -4,8 +4,11 @@ class HostHbaSyncStore extends HostPropertyInstancesSyncStore { - protected $baseKey = 'config.storageDevice.hostBusAdapter'; - protected $keyProperty = 'key'; - protected $dbKeyProperty = 'hba_key'; - protected $instanceClass = 'HostHostBusAdapter'; + protected string $baseKey = 'config.storageDevice.hostBusAdapter'; + + protected string $keyProperty = 'key'; + + protected string $dbKeyProperty = 'hba_key'; + + protected string $instanceClass = 'HostHostBusAdapter'; } diff --git a/library/Vspheredb/Polling/SyncStore/HostPhysicalNicSyncStore.php b/library/Vspheredb/Polling/SyncStore/HostPhysicalNicSyncStore.php index 4b00a75e..4c07139e 100644 --- a/library/Vspheredb/Polling/SyncStore/HostPhysicalNicSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/HostPhysicalNicSyncStore.php @@ -4,8 +4,11 @@ class HostPhysicalNicSyncStore extends HostPropertyInstancesSyncStore { - protected $baseKey = 'config.network.pnic'; - protected $keyProperty = 'key'; - protected $dbKeyProperty = 'nic_key'; - protected $instanceClass = 'PhysicalNic'; + protected string $baseKey = 'config.network.pnic'; + + protected string $keyProperty = 'key'; + + protected string $dbKeyProperty = 'nic_key'; + + protected string $instanceClass = 'PhysicalNic'; } diff --git a/library/Vspheredb/Polling/SyncStore/HostPropertyInstancesSyncStore.php b/library/Vspheredb/Polling/SyncStore/HostPropertyInstancesSyncStore.php index 3ffb1c46..05bda1d4 100644 --- a/library/Vspheredb/Polling/SyncStore/HostPropertyInstancesSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/HostPropertyInstancesSyncStore.php @@ -10,19 +10,21 @@ abstract class HostPropertyInstancesSyncStore extends SyncStore { use SyncHelper; - protected $baseKey = 'undefined.property'; - protected $keyProperty = 'undefinedKeyProperty'; - protected $dbKeyProperty = 'undefinedKeyProperty'; - protected $instanceClass = 'undefinedInstanceClass'; + protected string $baseKey = 'undefined.property'; - public function store($result, $class, SyncStats $stats) + protected string $keyProperty = 'undefinedKeyProperty'; + + protected string $dbKeyProperty = 'undefinedKeyProperty'; + + protected string $instanceClass = 'undefinedInstanceClass'; + + public function store($result, $class, SyncStats $stats): void { $connection = $this->vCenter->getConnection(); $dbObjects = $class::loadAllForVCenter($this->vCenter); $baseKey = $this->baseKey; $keyProperty = $this->keyProperty; - /** @var string $dbKeyProperty */ $dbKeyProperty = $this->dbKeyProperty; $instanceClass = $this->instanceClass; @@ -30,13 +32,9 @@ public function store($result, $class, SyncStats $stats) foreach ($result as $object) { $object = (object) $object; // Hint: this is now dealt with by makeBinaryGlobalMoRefUuid() - if ($object->obj instanceof ManagedObjectReference) { - $uuid = $this->vCenter->makeBinaryGlobalMoRefUuid($object->obj); - } else { - $uuid = $this->vCenter->makeBinaryGlobalMoRefUuid( - ManagedObjectReference::fromSerialization($object->obj) - ); - } + $uuid = $object->obj instanceof ManagedObjectReference + ? $this->vCenter->makeBinaryGlobalMoRefUuid($object->obj) + : $this->vCenter->makeBinaryGlobalMoRefUuid(ManagedObjectReference::fromSerialization($object->obj)); if (! isset($object->$baseKey) || ! property_exists($object->$baseKey, $instanceClass)) { // No instance information for this host continue; diff --git a/library/Vspheredb/Polling/SyncStore/HostSensorSyncStore.php b/library/Vspheredb/Polling/SyncStore/HostSensorSyncStore.php index 6343b5ae..c16312c9 100644 --- a/library/Vspheredb/Polling/SyncStore/HostSensorSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/HostSensorSyncStore.php @@ -4,8 +4,11 @@ class HostSensorSyncStore extends HostPropertyInstancesSyncStore { - protected $baseKey = 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'; - protected $keyProperty = 'name'; - protected $dbKeyProperty = 'name'; - protected $instanceClass = 'HostNumericSensorInfo'; + protected string $baseKey = 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'; + + protected string $keyProperty = 'name'; + + protected string $dbKeyProperty = 'name'; + + protected string $instanceClass = 'HostNumericSensorInfo'; } diff --git a/library/Vspheredb/Polling/SyncStore/HostVirtualNicSyncStore.php b/library/Vspheredb/Polling/SyncStore/HostVirtualNicSyncStore.php index 0ee8cfb9..967333b9 100644 --- a/library/Vspheredb/Polling/SyncStore/HostVirtualNicSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/HostVirtualNicSyncStore.php @@ -4,8 +4,11 @@ class HostVirtualNicSyncStore extends HostPropertyInstancesSyncStore { - protected $baseKey = 'config.network.vnic'; - protected $keyProperty = 'key'; - protected $dbKeyProperty = 'nic_key'; - protected $instanceClass = 'HostVirtualNic'; + protected string $baseKey = 'config.network.vnic'; + + protected string $keyProperty = 'key'; + + protected string $dbKeyProperty = 'nic_key'; + + protected string $instanceClass = 'HostVirtualNic'; } diff --git a/library/Vspheredb/Polling/SyncStore/ManagedObjectReferenceSyncStore.php b/library/Vspheredb/Polling/SyncStore/ManagedObjectReferenceSyncStore.php index 91e39934..69901428 100644 --- a/library/Vspheredb/Polling/SyncStore/ManagedObjectReferenceSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/ManagedObjectReferenceSyncStore.php @@ -13,7 +13,7 @@ class ManagedObjectReferenceSyncStore extends SyncStore { use SyncHelper; - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { $connection = $this->vCenter->getConnection(); $vCenter = $this->vCenter; @@ -47,6 +47,7 @@ public function store($result, $class, SyncStats $stats) $fetched[$uuid], Uuid::fromBytes($uuid)->toString() )); + return; } $fetched[$uuid] = $name; @@ -67,7 +68,7 @@ public function store($result, $class, SyncStats $stats) 'object_name' => $name, 'object_type' => $moRef->type, 'overall_status' => $obj->overallStatus, - 'tags' => JsonString::encode($tags), + 'tags' => JsonString::encode($tags) ], $connection); } if (property_exists($obj, 'parent')) { @@ -78,23 +79,18 @@ public function store($result, $class, SyncStats $stats) } if (! empty($vmUuidsWithNoParent)) { - $this->logger->debug(\sprintf( + $this->logger->debug(sprintf( 'There are %d VMs without parent', - \count($vmUuidsWithNoParent) + count($vmUuidsWithNoParent) )); } /** @var string $parentName */ foreach ($idToParent as $uuid => $parentName) { if (array_key_exists($parentName, $nameUuids)) { - $objects[$uuid]->setParent( - $objects[$nameUuids[$parentName]] - ); + $objects[$uuid]->setParent($objects[$nameUuids[$parentName]]); } else { - $this->logger->error(sprintf( - "Could not find parent $parentName for %s", - $fetched[$uuid] - )); + $this->logger->error(sprintf("Could not find parent $parentName for %s", $fetched[$uuid])); } } diff --git a/library/Vspheredb/Polling/SyncStore/ObjectSyncStore.php b/library/Vspheredb/Polling/SyncStore/ObjectSyncStore.php index 5244cc1e..a607fca6 100644 --- a/library/Vspheredb/Polling/SyncStore/ObjectSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/ObjectSyncStore.php @@ -15,8 +15,7 @@ class ObjectSyncStore extends SyncStore public const CUSTOM_VALUE_KEY = 'summary.customValue'; - /** @var ?array */ - protected $customFieldsMap; + protected ?array $customFieldsMap; public function __construct( $db, @@ -28,7 +27,7 @@ public function __construct( parent::__construct($db, $vCenter, $logger); } - protected function indexByUuid($result) + protected function indexByUuid($result): array { // map by key $fromApi = []; @@ -50,7 +49,7 @@ protected function indexByUuid($result) return $fromApi; } - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { $result = $this->indexByUuid($result); $dbObjects = $class::loadAllForVCenter($this->vCenter); @@ -72,7 +71,7 @@ public function store($result, $class, SyncStats $stats) $this->storeSyncObjects($connection->getDbAdapter(), $dbObjects, $result, $stats); } - protected static function mapResultCustomValues($object, array $map) + protected static function mapResultCustomValues($object, array $map): void { $key = self::CUSTOM_VALUE_KEY; if (isset($object->$key) && ! empty((array) $object->$key)) { diff --git a/library/Vspheredb/Polling/SyncStore/PerfCounterInfoSyncStore.php b/library/Vspheredb/Polling/SyncStore/PerfCounterInfoSyncStore.php index 9fbaae3d..86b1b885 100644 --- a/library/Vspheredb/Polling/SyncStore/PerfCounterInfoSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/PerfCounterInfoSyncStore.php @@ -14,7 +14,7 @@ class PerfCounterInfoSyncStore extends SyncStore { use SyncHelper; - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { if (! $result instanceof PerformanceManager) { throw new InvalidArgumentException('PerformanceManager expected, got: ' . var_export($result, 1)); @@ -27,9 +27,13 @@ public function store($result, $class, SyncStats $stats) * TODO: really sync * * @param PerfCounterInfo[] $infos + * @param SyncStats $stats + * + * @return void + * * @throws Exception */ - protected function processCounterInfo(array $infos, SyncStats $stats) + protected function processCounterInfo(array $infos, SyncStats $stats): void { $uuid = $this->vCenter->get('uuid'); $db = $this->vCenter->getDb(); @@ -47,7 +51,7 @@ protected function processCounterInfo(array $infos, SyncStats $stats) 'vcenter_uuid' => $uuid, 'name' => $group, 'label' => $info->groupInfo->label, - 'summary' => $info->groupInfo->summary, + 'summary' => $info->groupInfo->summary ]; } if (! array_key_exists($unit, $units)) { @@ -55,7 +59,7 @@ protected function processCounterInfo(array $infos, SyncStats $stats) 'vcenter_uuid' => $uuid, 'name' => $unit, 'label' => $info->unitInfo->label, - 'summary' => $info->unitInfo->summary, + 'summary' => $info->unitInfo->summary ]; } $counter = [ @@ -66,10 +70,10 @@ protected function processCounterInfo(array $infos, SyncStats $stats) 'unit_name' => $unit, 'label' => $info->nameInfo->label, 'summary' => $info->nameInfo->summary, - 'rollup_type' => (string) $info->rollupType, - 'stats_type' => (string) $info->statsType, + 'rollup_type' => $info->rollupType, + 'stats_type' => $info->statsType, 'level' => $info->level ?? 0, // ESXi? Check docs! - 'per_device_level' => $info->perDeviceLevel ?? 0, + 'per_device_level' => $info->perDeviceLevel ?? 0 ]; $counters[] = $counter; } diff --git a/library/Vspheredb/Polling/SyncStore/SyncStore.php b/library/Vspheredb/Polling/SyncStore/SyncStore.php index c9a3bfdc..402537ac 100644 --- a/library/Vspheredb/Polling/SyncStore/SyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/SyncStore.php @@ -2,33 +2,30 @@ namespace Icinga\Module\Vspheredb\Polling\SyncStore; -use gipfl\ZfDb\Adapter\Adapter; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\SyncRelated\SyncStats; use Psr\Log\LoggerInterface; +use Zend_Db_Adapter_Abstract; abstract class SyncStore { - /** @var Adapter|\Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; /** - * @param Adapter|\Zend_Db_Adapter_Abstract $db + * @param Zend_Db_Adapter_Abstract $db * @param VCenter $vCenter * @param LoggerInterface $logger */ - public function __construct($db, VCenter $vCenter, LoggerInterface $logger) + public function __construct(Zend_Db_Adapter_Abstract $db, VCenter $vCenter, LoggerInterface $logger) { $this->db = $db; $this->vCenter = $vCenter; $this->logger = $logger; } - abstract public function store($result, $class, SyncStats $stats); + abstract public function store($result, $class, SyncStats $stats): void; } diff --git a/library/Vspheredb/Polling/SyncStore/TaggingSyncStore.php b/library/Vspheredb/Polling/SyncStore/TaggingSyncStore.php index 63140ba0..a45f899f 100644 --- a/library/Vspheredb/Polling/SyncStore/TaggingSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/TaggingSyncStore.php @@ -10,7 +10,7 @@ class TaggingSyncStore extends SyncStore { use SyncHelper; - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { $result = self::wantBinaryUuids($result); $dbObjects = $class::loadAllForVCenter($this->vCenter); @@ -21,9 +21,7 @@ public function store($result, $class, SyncStats $stats) if (array_key_exists($idx, $dbObjects)) { $dbObject = $dbObjects[$idx]; } else { - $dbObjects[$idx] = $dbObject = $class::create([ - 'vcenter_uuid' => $vCenterUuid - ], $connection); + $dbObjects[$idx] = $dbObject = $class::create(['vcenter_uuid' => $vCenterUuid], $connection); } $dbObject->setMapped($object, $this->vCenter); } diff --git a/library/Vspheredb/Polling/SyncStore/VmDatastoreUsageSyncStore.php b/library/Vspheredb/Polling/SyncStore/VmDatastoreUsageSyncStore.php index cc7ad2d2..9695d7c6 100644 --- a/library/Vspheredb/Polling/SyncStore/VmDatastoreUsageSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/VmDatastoreUsageSyncStore.php @@ -10,6 +10,8 @@ use Icinga\Module\Vspheredb\Util; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; use Psr\Log\LoggerInterface; +use React\Promise\PromiseInterface; +use Zend_Db_Adapter_Abstract; use function React\Promise\all; use function React\Promise\resolve; @@ -20,7 +22,7 @@ class VmDatastoreUsageSyncStore extends SyncStore // Refresh outdated VMs -> before and after? - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { $vCenter = $this->vCenter; $vCenterUuid = $vCenter->getUuid(); @@ -35,11 +37,9 @@ public function store($result, $class, SyncStats $stats) if (! isset($map->{'storage.perDatastoreUsage'}->{'VirtualMachineUsageOnDatastore'})) { continue; } - if (isset($map->{'storage.timestamp'})) { - $timestamp = Util::timeStringToUnixMs($map->{'storage.timestamp'}); - } else { - $timestamp = null; - } + $timestamp = isset($map->{'storage.timestamp'}) + ? Util::timeStringToUnixMs($map->{'storage.timestamp'}) + : null; foreach ($map->{'storage.perDatastoreUsage'}->{'VirtualMachineUsageOnDatastore'} as $usage) { $dsUuid = $vCenter->makeBinaryGlobalMoRefUuid($usage->datastore); $key = "$vmUuid$dsUuid"; @@ -47,7 +47,7 @@ public function store($result, $class, SyncStats $stats) 'committed' => $usage->committed, 'uncommitted' => $usage->uncommitted, 'unshared' => $usage->unshared, - 'ts_updated' => $timestamp, + 'ts_updated' => $timestamp ]; $seen[$key] = $key; if (array_key_exists($key, $dbObjects)) { @@ -65,7 +65,7 @@ public function store($result, $class, SyncStats $stats) $this->storeSyncObjects($connection->getDbAdapter(), $dbObjects, $seen, $stats); } - public static function fetchOutdatedVms(VCenter $vCenter, $lastRefreshSecondsAgo = 1800, $cntMax = null) + public static function fetchOutdatedVms(VCenter $vCenter, $lastRefreshSecondsAgo = 1800, $cntMax = null): array { $db = $vCenter->getDb(); $vCenterUuid = $vCenter->get('uuid'); @@ -75,7 +75,7 @@ public static function fetchOutdatedVms(VCenter $vCenter, $lastRefreshSecondsAgo $query = $db->select()->from(['o' => 'object'], [ 'moref' => 'o.moref', - 'object_name' => 'o.object_name', + 'object_name' => 'o.object_name' ])->join( ['vm' => 'virtual_machine'], "vm.uuid = o.uuid AND vm.template = 'n' AND vm.runtime_power_state = 'poweredOn'", @@ -98,7 +98,7 @@ public static function fetchOutdatedVms(VCenter $vCenter, $lastRefreshSecondsAgo return $db->fetchPairs($query); } - public static function refreshOutdatedVms(VsphereApi $api, $vms, LoggerInterface $logger) + public static function refreshOutdatedVms(VsphereApi $api, $vms, LoggerInterface $logger): PromiseInterface { if (empty($vms)) { return resolve(null); @@ -117,7 +117,7 @@ public static function refreshOutdatedVms(VsphereApi $api, $vms, LoggerInterface return all($pending); } - protected function makeWhere(\Zend_Db_Adapter_Abstract $db, $vmUuid, $dsUuid) + protected function makeWhere(Zend_Db_Adapter_Abstract $db, $vmUuid, $dsUuid): string { return $db->quoteInto('vm_uuid = ?', $vmUuid) . $db->quoteInto(' AND datastore_uuid = ?', $dsUuid); diff --git a/library/Vspheredb/Polling/SyncStore/VmDiskUsageSyncStore.php b/library/Vspheredb/Polling/SyncStore/VmDiskUsageSyncStore.php index 34e0adbe..cee10c05 100644 --- a/library/Vspheredb/Polling/SyncStore/VmDiskUsageSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/VmDiskUsageSyncStore.php @@ -5,12 +5,13 @@ use Icinga\Module\Vspheredb\SyncRelated\SyncHelper; use Icinga\Module\Vspheredb\SyncRelated\SyncStats; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; +use stdClass; class VmDiskUsageSyncStore extends SyncStore { use SyncHelper; - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { $vCenter = $this->vCenter; $vCenterUuid = $vCenter->getUuid(); @@ -22,11 +23,9 @@ public function store($result, $class, SyncStats $stats) $skipUuids = []; foreach ($result as $object) { $object = (object) $object; - if ($object->obj instanceof ManagedObjectReference) { - $uuid = $vCenter->makeBinaryGlobalMoRefUuid($object->obj); - } else { - $uuid = $vCenter->makeBinaryGlobalMoRefUuid(ManagedObjectReference::fromSerialization($object->obj)); - } + $uuid = $object->obj instanceof ManagedObjectReference + ? $vCenter->makeBinaryGlobalMoRefUuid($object->obj) + : $vCenter->makeBinaryGlobalMoRefUuid(ManagedObjectReference::fromSerialization($object->obj)); if (! property_exists($object->{'guest.disk'}, 'GuestDiskInfo')) { $skipUuids[] = $uuid; // Preserve former disks. Should we flag them as outdated? @@ -47,17 +46,10 @@ public function store($result, $class, SyncStats $stats) } elseif ($path === '/var') { $var = $info; } elseif (is_object($root) && in_array($path, ['/tmp', '/var/tmp'])) { - if ($path === '/var/tmp' && is_object($var)) { - $base = $var; - } else { - $base = $root; - } + $base = $path === '/var/tmp' && is_object($var) ? $var : $root; - /** @var \stdClass $base */ - if ( - $info->capacity === $base->capacity - && $info->freeSpace === $base->freeSpace - ) { + /** @var stdClass $base */ + if ($info->capacity === $base->capacity && $info->freeSpace === $base->freeSpace) { continue; } } @@ -90,7 +82,7 @@ public function store($result, $class, SyncStats $stats) 'vcenter_uuid' => $vCenterUuid, 'disk_path' => $path, 'capacity' => $info->capacity, - 'free_space' => $info->freeSpace, + 'free_space' => $info->freeSpace ], $connection); } } diff --git a/library/Vspheredb/Polling/SyncStore/VmEventHistorySyncStore.php b/library/Vspheredb/Polling/SyncStore/VmEventHistorySyncStore.php index 47285d2a..3fc2dd4c 100644 --- a/library/Vspheredb/Polling/SyncStore/VmEventHistorySyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/VmEventHistorySyncStore.php @@ -2,20 +2,24 @@ namespace Icinga\Module\Vspheredb\Polling\SyncStore; +use gipfl\ZfDb\Exception\SelectException; use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\MappedClass\KnownEvent; use Icinga\Module\Vspheredb\SyncRelated\SyncHelper; use Icinga\Module\Vspheredb\SyncRelated\SyncStats; use RuntimeException; +use Zend_Db_Adapter_Abstract; +use Zend_Db_Select_Exception; class VmEventHistorySyncStore extends SyncStore { use SyncHelper; - protected $lastEventKey; - protected $lastEventTimestamp; + protected ?int $lastEventKey = null; - public function store($result, $class, SyncStats $stats) + protected ?int $lastEventTimestamp = null; + + public function store($result, $class, SyncStats $stats): void { if (empty($result)) { return; @@ -25,7 +29,7 @@ public function store($result, $class, SyncStats $stats) $this->lastEventKey = $this->getLastEventKey(); $this->lastEventTimestamp = $this->getLastEventTimeStamp(); $stats->setFromApi(count($result)); - foreach ($result as $key => $event) { + foreach ($result as $event) { if (! isset($event->__class)) { $this->logger->error(json_encode($event)); return; @@ -70,31 +74,34 @@ public function store($result, $class, SyncStats $stats) /** * @return int - * @throws \Zend_Db_Select_Exception - * @throws \gipfl\ZfDb\Exception\SelectException + * + * @throws Zend_Db_Select_Exception + * @throws SelectException */ - protected function getLastEventKey() + protected function getLastEventKey(): int { return static::selectLast($this->db, $this->vCenter->getUuid(), 'event_key'); } /** * @return int - * @throws \Zend_Db_Select_Exception - * @throws \gipfl\ZfDb\Exception\SelectException + * + * @throws Zend_Db_Select_Exception + * @throws SelectException */ - public function getLastEventTimeStamp() + public function getLastEventTimeStamp(): int { return static::selectLast($this->db, $this->vCenter->getUuid(), 'ts_event_ms'); } /** - * @param $db + * @param Zend_Db_Adapter_Abstract $db * @param string $vCenterUuid * @param string $column + * * @return int */ - public static function selectLast($db, $vCenterUuid, $column) + public static function selectLast(Zend_Db_Adapter_Abstract $db, $vCenterUuid, string $column): int { $union = $db->select()->union([ 'vmeh' => $db->select()->from( @@ -104,7 +111,7 @@ public static function selectLast($db, $vCenterUuid, $column) 'ah' => $db->select()->from( 'alarm_history', [$column => "MAX($column)"] - )->where('vcenter_uuid = ?', $vCenterUuid), + )->where('vcenter_uuid = ?', $vCenterUuid) ], Select::SQL_UNION_ALL); return (int) $db->fetchOne( diff --git a/library/Vspheredb/Polling/SyncStore/VmHardwareSyncStore.php b/library/Vspheredb/Polling/SyncStore/VmHardwareSyncStore.php index c214792f..4026eeac 100644 --- a/library/Vspheredb/Polling/SyncStore/VmHardwareSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/VmHardwareSyncStore.php @@ -13,7 +13,7 @@ class VmHardwareSyncStore extends SyncStore { use SyncHelper; - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { $vCenter = $this->vCenter; $connection = $vCenter->getConnection(); @@ -83,13 +83,10 @@ public function store($result, $class, SyncStats $stats) $this->storeSyncObjects($connection->getDbAdapter(), $nics, $seen, $ignoreNicStats); } - protected function assertValidDeviceKey($device) + protected function assertValidDeviceKey($device): void { if (! is_int($device->key)) { - throw new InvalidArgumentException( - 'Got invalid device key "%s", integer expected', - $device->key - ); + throw new InvalidArgumentException('Got invalid device key "%s", integer expected', $device->key); } } } diff --git a/library/Vspheredb/Polling/SyncStore/VmSnapshotSyncStore.php b/library/Vspheredb/Polling/SyncStore/VmSnapshotSyncStore.php index ca3bc196..ce96651f 100644 --- a/library/Vspheredb/Polling/SyncStore/VmSnapshotSyncStore.php +++ b/library/Vspheredb/Polling/SyncStore/VmSnapshotSyncStore.php @@ -10,7 +10,7 @@ class VmSnapshotSyncStore extends SyncStore { use SyncHelper; - public function store($result, $class, SyncStats $stats) + public function store($result, $class, SyncStats $stats): void { $vCenter = $this->vCenter; $vCenterUuid = $vCenter->getUuid(); diff --git a/library/Vspheredb/Polling/SyncTask/ComputeResourceSyncTask.php b/library/Vspheredb/Polling/SyncTask/ComputeResourceSyncTask.php index 4a1fd694..d7b2ae6c 100644 --- a/library/Vspheredb/Polling/SyncTask/ComputeResourceSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/ComputeResourceSyncTask.php @@ -9,10 +9,15 @@ class ComputeResourceSyncTask extends SyncTask { - protected $label = 'Compute Resources'; - protected $tableName = 'compute_resource'; - protected $objectClass = ComputeResource::class; - protected $selectSetClass = ComputeResourceSelectSet::class; - protected $propertySetClass = ComputeResourcePropertySet::class; - protected $syncStoreClass = ObjectSyncStore::class; + protected string $label = 'Compute Resources'; + + protected string $tableName = 'compute_resource'; + + protected string $objectClass = ComputeResource::class; + + protected string $selectSetClass = ComputeResourceSelectSet::class; + + protected string $propertySetClass = ComputeResourcePropertySet::class; + + protected string $syncStoreClass = ObjectSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/DatastoreSyncTask.php b/library/Vspheredb/Polling/SyncTask/DatastoreSyncTask.php index ec467349..caf38e4a 100644 --- a/library/Vspheredb/Polling/SyncTask/DatastoreSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/DatastoreSyncTask.php @@ -9,10 +9,15 @@ class DatastoreSyncTask extends SyncTask { - protected $label = 'Data Stores'; - protected $tableName = 'datastore'; - protected $objectClass = Datastore::class; - protected $selectSetClass = DatastoreSelectSet::class; - protected $propertySetClass = DatastorePropertySet::class; - protected $syncStoreClass = ObjectSyncStore::class; + protected string $label = 'Data Stores'; + + protected string $tableName = 'datastore'; + + protected string $objectClass = Datastore::class; + + protected string $selectSetClass = DatastoreSelectSet::class; + + protected string $propertySetClass = DatastorePropertySet::class; + + protected string $syncStoreClass = ObjectSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/HostHardwareSyncTask.php b/library/Vspheredb/Polling/SyncTask/HostHardwareSyncTask.php index ad64a5f0..b70db8ed 100644 --- a/library/Vspheredb/Polling/SyncTask/HostHardwareSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/HostHardwareSyncTask.php @@ -9,10 +9,15 @@ class HostHardwareSyncTask extends SyncTask { - protected $label = 'Host Hardware'; - protected $tableName = 'host_pci_device'; - protected $objectClass = HostPciDevice::class; - protected $selectSetClass = HostSystemSelectSet::class; - protected $propertySetClass = HostHardwarePropertySet::class; - protected $syncStoreClass = HostHardwareSyncStore::class; + protected string $label = 'Host Hardware'; + + protected string $tableName = 'host_pci_device'; + + protected string $objectClass = HostPciDevice::class; + + protected string $selectSetClass = HostSystemSelectSet::class; + + protected string $propertySetClass = HostHardwarePropertySet::class; + + protected string $syncStoreClass = HostHardwareSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/HostHbaSyncTask.php b/library/Vspheredb/Polling/SyncTask/HostHbaSyncTask.php index 50b6f586..22c8955c 100644 --- a/library/Vspheredb/Polling/SyncTask/HostHbaSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/HostHbaSyncTask.php @@ -9,10 +9,15 @@ class HostHbaSyncTask extends SyncTask { - protected $label = 'Host HBAs'; - protected $tableName = 'host_hba'; - protected $objectClass = HostHba::class; - protected $selectSetClass = HostSystemSelectSet::class; - protected $propertySetClass = HostHbaPropertySet::class; - protected $syncStoreClass = HostHbaSyncStore::class; + protected string $label = 'Host HBAs'; + + protected string $tableName = 'host_hba'; + + protected string $objectClass = HostHba::class; + + protected string $selectSetClass = HostSystemSelectSet::class; + + protected string $propertySetClass = HostHbaPropertySet::class; + + protected string $syncStoreClass = HostHbaSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/HostPhysicalNicSyncTask.php b/library/Vspheredb/Polling/SyncTask/HostPhysicalNicSyncTask.php index ec414e19..59e063f8 100644 --- a/library/Vspheredb/Polling/SyncTask/HostPhysicalNicSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/HostPhysicalNicSyncTask.php @@ -9,10 +9,15 @@ class HostPhysicalNicSyncTask extends SyncTask { - protected $label = 'Host Physical NICs'; - protected $tableName = 'host_physical_nic'; - protected $objectClass = HostPhysicalNic::class; - protected $selectSetClass = HostSystemSelectSet::class; - protected $propertySetClass = HostPhysicalNicPropertySet::class; - protected $syncStoreClass = HostPhysicalNicSyncStore::class; + protected string $label = 'Host Physical NICs'; + + protected string $tableName = 'host_physical_nic'; + + protected string $objectClass = HostPhysicalNic::class; + + protected string $selectSetClass = HostSystemSelectSet::class; + + protected string $propertySetClass = HostPhysicalNicPropertySet::class; + + protected string $syncStoreClass = HostPhysicalNicSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/HostQuickStatsSyncTask.php b/library/Vspheredb/Polling/SyncTask/HostQuickStatsSyncTask.php index 89d7f6ae..7ec40d85 100644 --- a/library/Vspheredb/Polling/SyncTask/HostQuickStatsSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/HostQuickStatsSyncTask.php @@ -9,10 +9,15 @@ class HostQuickStatsSyncTask extends SyncTask { - protected $label = 'Host Quick Stats'; - protected $tableName = 'host_quick_stats'; - protected $objectClass = HostQuickStats::class; - protected $selectSetClass = HostSystemSelectSet::class; - protected $propertySetClass = HostQuickStatsPropertySet::class; - protected $syncStoreClass = ObjectSyncStore::class; + protected string $label = 'Host Quick Stats'; + + protected string $tableName = 'host_quick_stats'; + + protected string $objectClass = HostQuickStats::class; + + protected string $selectSetClass = HostSystemSelectSet::class; + + protected string $propertySetClass = HostQuickStatsPropertySet::class; + + protected string $syncStoreClass = ObjectSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/HostSensorSyncTask.php b/library/Vspheredb/Polling/SyncTask/HostSensorSyncTask.php index 1022b0e9..ae43af54 100644 --- a/library/Vspheredb/Polling/SyncTask/HostSensorSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/HostSensorSyncTask.php @@ -9,10 +9,15 @@ class HostSensorSyncTask extends SyncTask { - protected $label = 'Host Sensors'; - protected $tableName = 'host_sensor'; - protected $objectClass = HostSensor::class; - protected $selectSetClass = HostSystemSelectSet::class; - protected $propertySetClass = HostSensorsPropertySet::class; - protected $syncStoreClass = HostSensorSyncStore::class; + protected string $label = 'Host Sensors'; + + protected string $tableName = 'host_sensor'; + + protected string $objectClass = HostSensor::class; + + protected string $selectSetClass = HostSystemSelectSet::class; + + protected string $propertySetClass = HostSensorsPropertySet::class; + + protected string $syncStoreClass = HostSensorSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/HostSystemSyncTask.php b/library/Vspheredb/Polling/SyncTask/HostSystemSyncTask.php index 2878f528..0fc59aee 100644 --- a/library/Vspheredb/Polling/SyncTask/HostSystemSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/HostSystemSyncTask.php @@ -9,10 +9,15 @@ class HostSystemSyncTask extends SyncTask { - protected $label = 'Host Systems'; - protected $tableName = 'host_system'; - protected $objectClass = HostSystem::class; - protected $selectSetClass = HostSystemSelectSet::class; - protected $propertySetClass = HostSystemPropertySet::class; - protected $syncStoreClass = ObjectSyncStore::class; + protected string $label = 'Host Systems'; + + protected string $tableName = 'host_system'; + + protected string $objectClass = HostSystem::class; + + protected string $selectSetClass = HostSystemSelectSet::class; + + protected string $propertySetClass = HostSystemPropertySet::class; + + protected string $syncStoreClass = ObjectSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/HostVirtualNicSyncTask.php b/library/Vspheredb/Polling/SyncTask/HostVirtualNicSyncTask.php index fb3385dd..4c2d95cf 100644 --- a/library/Vspheredb/Polling/SyncTask/HostVirtualNicSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/HostVirtualNicSyncTask.php @@ -9,10 +9,15 @@ class HostVirtualNicSyncTask extends SyncTask { - protected $label = 'Host Virtual NICs'; - protected $tableName = 'host_virtual_nic'; - protected $objectClass = HostVirtualNic::class; - protected $selectSetClass = HostSystemSelectSet::class; - protected $propertySetClass = HostVirtualNicPropertySet::class; - protected $syncStoreClass = HostVirtualNicSyncStore::class; + protected string $label = 'Host Virtual NICs'; + + protected string $tableName = 'host_virtual_nic'; + + protected string $objectClass = HostVirtualNic::class; + + protected string $selectSetClass = HostSystemSelectSet::class; + + protected string $propertySetClass = HostVirtualNicPropertySet::class; + + protected string $syncStoreClass = HostVirtualNicSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/ManagedObjectReferenceSyncTask.php b/library/Vspheredb/Polling/SyncTask/ManagedObjectReferenceSyncTask.php index f4eadd5a..99c71c93 100644 --- a/library/Vspheredb/Polling/SyncTask/ManagedObjectReferenceSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/ManagedObjectReferenceSyncTask.php @@ -9,10 +9,15 @@ class ManagedObjectReferenceSyncTask extends SyncTask { - protected $label = 'Managed Object References'; - protected $tableName = 'object'; - protected $objectClass = ManagedObject::class; - protected $selectSetClass = FullSelectSet::class; - protected $propertySetClass = FullObjectListPropertySet::class; - protected $syncStoreClass = ManagedObjectReferenceSyncStore::class; + protected string $label = 'Managed Object References'; + + protected string $tableName = 'object'; + + protected string $objectClass = ManagedObject::class; + + protected string $selectSetClass = FullSelectSet::class; + + protected string $propertySetClass = FullObjectListPropertySet::class; + + protected string $syncStoreClass = ManagedObjectReferenceSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/StoragePodSyncTask.php b/library/Vspheredb/Polling/SyncTask/StoragePodSyncTask.php index 45d82b50..d4343191 100644 --- a/library/Vspheredb/Polling/SyncTask/StoragePodSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/StoragePodSyncTask.php @@ -9,10 +9,15 @@ class StoragePodSyncTask extends SyncTask { - protected $label = 'Storage Pods'; - protected $tableName = 'storage_pod'; - protected $objectClass = StoragePod::class; - protected $selectSetClass = StoragePodSelectSet::class; - protected $propertySetClass = StoragePodPropertySet::class; - protected $syncStoreClass = ObjectSyncStore::class; + protected string $label = 'Storage Pods'; + + protected string $tableName = 'storage_pod'; + + protected string $objectClass = StoragePod::class; + + protected string $selectSetClass = StoragePodSelectSet::class; + + protected string $propertySetClass = StoragePodPropertySet::class; + + protected string $syncStoreClass = ObjectSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/SyncTask.php b/library/Vspheredb/Polling/SyncTask/SyncTask.php index 85e691ad..49263835 100644 --- a/library/Vspheredb/Polling/SyncTask/SyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/SyncTask.php @@ -10,23 +10,17 @@ abstract class SyncTask { public const UNSPECIFIED = 'unspecified'; - /** @var string */ - protected $label = self::UNSPECIFIED; + protected string $label = self::UNSPECIFIED; - /** @var string */ - protected $tableName = self::UNSPECIFIED; + protected string $tableName = self::UNSPECIFIED; - /** @var string */ - protected $objectClass = self::UNSPECIFIED; + protected string $objectClass = self::UNSPECIFIED; - /** @var string */ - protected $selectSetClass = self::UNSPECIFIED; + protected string $selectSetClass = self::UNSPECIFIED; - /** @var string */ - protected $propertySetClass = self::UNSPECIFIED; + protected string $propertySetClass = self::UNSPECIFIED; - /** @var string */ - protected $syncStoreClass = self::UNSPECIFIED; + protected string $syncStoreClass = self::UNSPECIFIED; public function getLabel(): string { diff --git a/library/Vspheredb/Polling/SyncTask/TaggingCategorySyncTask.php b/library/Vspheredb/Polling/SyncTask/TaggingCategorySyncTask.php index ed73b8a0..d3eacffc 100644 --- a/library/Vspheredb/Polling/SyncTask/TaggingCategorySyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/TaggingCategorySyncTask.php @@ -8,9 +8,11 @@ class TaggingCategorySyncTask extends TaggingSyncTask { - protected $label = 'Tag Categories'; - protected $tableName = TaggingCategory::TABLE; - protected $objectClass = TaggingCategory::class; + protected string $label = 'Tag Categories'; + + protected string $tableName = TaggingCategory::TABLE; + + protected string $objectClass = TaggingCategory::class; public function run(RestApi $api): PromiseInterface { diff --git a/library/Vspheredb/Polling/SyncTask/TaggingObjectTagSyncTask.php b/library/Vspheredb/Polling/SyncTask/TaggingObjectTagSyncTask.php index 9f9060ff..375dbf3b 100644 --- a/library/Vspheredb/Polling/SyncTask/TaggingObjectTagSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/TaggingObjectTagSyncTask.php @@ -8,9 +8,11 @@ class TaggingObjectTagSyncTask extends TaggingSyncTask { - protected $label = 'Object Tags'; - protected $tableName = TaggingObjectTag::TABLE; - protected $objectClass = TaggingObjectTag::class; + protected string $label = 'Object Tags'; + + protected string $tableName = TaggingObjectTag::TABLE; + + protected string $objectClass = TaggingObjectTag::class; public function run(RestApi $api): PromiseInterface { diff --git a/library/Vspheredb/Polling/SyncTask/TaggingSyncTask.php b/library/Vspheredb/Polling/SyncTask/TaggingSyncTask.php index 2c5f9f1a..9fd53694 100644 --- a/library/Vspheredb/Polling/SyncTask/TaggingSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/TaggingSyncTask.php @@ -6,5 +6,5 @@ abstract class TaggingSyncTask extends SyncTask implements RestApiTask { - protected $syncStoreClass = TaggingSyncStore::class; + protected string $syncStoreClass = TaggingSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/TaggingTagSyncTask.php b/library/Vspheredb/Polling/SyncTask/TaggingTagSyncTask.php index 10d96083..90073c99 100644 --- a/library/Vspheredb/Polling/SyncTask/TaggingTagSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/TaggingTagSyncTask.php @@ -8,9 +8,11 @@ class TaggingTagSyncTask extends TaggingSyncTask { - protected $label = 'Tags'; - protected $tableName = TaggingTag::TABLE; - protected $objectClass = TaggingTag::class; + protected string $label = 'Tags'; + + protected string $tableName = TaggingTag::TABLE; + + protected string $objectClass = TaggingTag::class; public function run(RestApi $api): PromiseInterface { diff --git a/library/Vspheredb/Polling/SyncTask/VirtualMachineSyncTask.php b/library/Vspheredb/Polling/SyncTask/VirtualMachineSyncTask.php index 1ce11f1c..272ea76f 100644 --- a/library/Vspheredb/Polling/SyncTask/VirtualMachineSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/VirtualMachineSyncTask.php @@ -9,10 +9,15 @@ class VirtualMachineSyncTask extends SyncTask { - protected $label = 'Virtual Machines'; - protected $tableName = 'virtual_machine'; - protected $objectClass = VirtualMachine::class; - protected $selectSetClass = VirtualMachineSelectSet::class; - protected $propertySetClass = VirtualMachinePropertySet::class; - protected $syncStoreClass = ObjectSyncStore::class; + protected string $label = 'Virtual Machines'; + + protected string $tableName = 'virtual_machine'; + + protected string $objectClass = VirtualMachine::class; + + protected string $selectSetClass = VirtualMachineSelectSet::class; + + protected string $propertySetClass = VirtualMachinePropertySet::class; + + protected string $syncStoreClass = ObjectSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/VmDatastoreUsageSyncTask.php b/library/Vspheredb/Polling/SyncTask/VmDatastoreUsageSyncTask.php index d6c32580..5046fcf9 100644 --- a/library/Vspheredb/Polling/SyncTask/VmDatastoreUsageSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/VmDatastoreUsageSyncTask.php @@ -10,10 +10,15 @@ class VmDatastoreUsageSyncTask extends SyncTask { // TODO: refresh logic! -> pick outdated ones, trigger refresh - protected $label = 'VM Datastore Usage'; - protected $tableName = 'vm_datastore_usage'; - protected $objectClass = VmDatastoreUsage::class; - protected $selectSetClass = VirtualMachineSelectSet::class; - protected $propertySetClass = VmDatastoreUsagePropertySet::class; - protected $syncStoreClass = VmDatastoreUsageSyncStore::class; + protected string $label = 'VM Datastore Usage'; + + protected string $tableName = 'vm_datastore_usage'; + + protected string $objectClass = VmDatastoreUsage::class; + + protected string $selectSetClass = VirtualMachineSelectSet::class; + + protected string $propertySetClass = VmDatastoreUsagePropertySet::class; + + protected string $syncStoreClass = VmDatastoreUsageSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/VmDiskUsageSyncTask.php b/library/Vspheredb/Polling/SyncTask/VmDiskUsageSyncTask.php index 243cf30a..57405057 100644 --- a/library/Vspheredb/Polling/SyncTask/VmDiskUsageSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/VmDiskUsageSyncTask.php @@ -9,10 +9,15 @@ class VmDiskUsageSyncTask extends SyncTask { - protected $label = 'VM Disk Usage'; - protected $tableName = 'vm_disk_usage'; - protected $objectClass = VmDiskUsage::class; - protected $selectSetClass = VirtualMachineSelectSet::class; - protected $propertySetClass = VmDiskUsagePropertySet::class; - protected $syncStoreClass = VmDiskUsageSyncStore::class; + protected string $label = 'VM Disk Usage'; + + protected string $tableName = 'vm_disk_usage'; + + protected string $objectClass = VmDiskUsage::class; + + protected string $selectSetClass = VirtualMachineSelectSet::class; + + protected string $propertySetClass = VmDiskUsagePropertySet::class; + + protected string $syncStoreClass = VmDiskUsageSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/VmEventHistorySyncTask.php b/library/Vspheredb/Polling/SyncTask/VmEventHistorySyncTask.php index 003f0898..45f08b82 100644 --- a/library/Vspheredb/Polling/SyncTask/VmEventHistorySyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/VmEventHistorySyncTask.php @@ -9,9 +9,11 @@ class VmEventHistorySyncTask extends SyncTask implements StandaloneTask { - protected $label = 'Events'; - protected $tableName = 'vm_event_history'; - protected $syncStoreClass = VmEventHistorySyncStore::class; + protected string $label = 'Events'; + + protected string $tableName = 'vm_event_history'; + + protected string $syncStoreClass = VmEventHistorySyncStore::class; public function run(VsphereApi $api, LoggerInterface $logger): PromiseInterface { diff --git a/library/Vspheredb/Polling/SyncTask/VmHardwareSyncTask.php b/library/Vspheredb/Polling/SyncTask/VmHardwareSyncTask.php index 697100d6..24652824 100644 --- a/library/Vspheredb/Polling/SyncTask/VmHardwareSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/VmHardwareSyncTask.php @@ -2,7 +2,6 @@ namespace Icinga\Module\Vspheredb\Polling\SyncTask; -use gipfl\Json\JsonString; use Icinga\Module\Vspheredb\DbObject\VmHardware; use Icinga\Module\Vspheredb\Polling\PropertySet\VmHardwarePropertySet; use Icinga\Module\Vspheredb\Polling\SelectSet\VirtualMachineSelectSet; @@ -10,14 +9,19 @@ class VmHardwareSyncTask extends SyncTask { - protected $label = 'VM Hardware'; - protected $tableName = 'vm_hardware'; - protected $objectClass = VmHardware::class; - protected $selectSetClass = VirtualMachineSelectSet::class; - protected $propertySetClass = VmHardwarePropertySet::class; - protected $syncStoreClass = VmHardwareSyncStore::class; + protected string $label = 'VM Hardware'; - public function tweakResult($result) + protected string $tableName = 'vm_hardware'; + + protected string $objectClass = VmHardware::class; + + protected string $selectSetClass = VirtualMachineSelectSet::class; + + protected string $propertySetClass = VmHardwarePropertySet::class; + + protected string $syncStoreClass = VmHardwareSyncStore::class; + + public function tweakResult($result): void { $whitelist = [ // Problem with config.hardware: some properties are binary, @@ -45,10 +49,10 @@ public function tweakResult($result) 'capacityInBytes', 'split', 'writeThrough', - 'thinProvisioned', + 'thinProvisioned' ]; // $unset = []; // used only when looking for new properties - foreach ($result as $key => $value) { + foreach ($result as $value) { if (isset($value['config.hardware']->device)) { foreach ($value['config.hardware']->device as $device) { foreach (array_keys((array) $device) as $k) { diff --git a/library/Vspheredb/Polling/SyncTask/VmQuickStatsSyncTask.php b/library/Vspheredb/Polling/SyncTask/VmQuickStatsSyncTask.php index d76501d7..03584e91 100644 --- a/library/Vspheredb/Polling/SyncTask/VmQuickStatsSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/VmQuickStatsSyncTask.php @@ -9,10 +9,15 @@ class VmQuickStatsSyncTask extends SyncTask { - protected $label = 'VM Quick Stats'; - protected $tableName = 'vm_quick_stats'; - protected $objectClass = VmQuickStats::class; - protected $selectSetClass = VirtualMachineSelectSet::class; - protected $propertySetClass = VmQuickStatsPropertySet::class; - protected $syncStoreClass = ObjectSyncStore::class; + protected string $label = 'VM Quick Stats'; + + protected string $tableName = 'vm_quick_stats'; + + protected string $objectClass = VmQuickStats::class; + + protected string $selectSetClass = VirtualMachineSelectSet::class; + + protected string $propertySetClass = VmQuickStatsPropertySet::class; + + protected string $syncStoreClass = ObjectSyncStore::class; } diff --git a/library/Vspheredb/Polling/SyncTask/VmSnapshotSyncTask.php b/library/Vspheredb/Polling/SyncTask/VmSnapshotSyncTask.php index c3dfec1f..2e03a958 100644 --- a/library/Vspheredb/Polling/SyncTask/VmSnapshotSyncTask.php +++ b/library/Vspheredb/Polling/SyncTask/VmSnapshotSyncTask.php @@ -9,10 +9,15 @@ class VmSnapshotSyncTask extends SyncTask { - protected $label = 'VM Snapshots'; - protected $tableName = 'vm_snapshot'; - protected $objectClass = VmSnapshot::class; - protected $selectSetClass = VirtualMachineSelectSet::class; - protected $propertySetClass = VmSnapshotPropertySet::class; - protected $syncStoreClass = VmSnapshotSyncStore::class; + protected string $label = 'VM Snapshots'; + + protected string $tableName = 'vm_snapshot'; + + protected string $objectClass = VmSnapshot::class; + + protected string $selectSetClass = VirtualMachineSelectSet::class; + + protected string $propertySetClass = VmSnapshotPropertySet::class; + + protected string $syncStoreClass = VmSnapshotSyncStore::class; } diff --git a/library/Vspheredb/Polling/VsphereApi.php b/library/Vspheredb/Polling/VsphereApi.php index 3258ddc0..dcc83a90 100644 --- a/library/Vspheredb/Polling/VsphereApi.php +++ b/library/Vspheredb/Polling/VsphereApi.php @@ -28,52 +28,47 @@ use Icinga\Module\Vspheredb\Polling\SelectSet\SelectSet; use Icinga\Module\Vspheredb\SafeCacheDir; use Icinga\Module\Vspheredb\VmwareDataType\ManagedObjectReference; +use InvalidArgumentException; use Psr\Log\LoggerInterface; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use React\EventLoop\LoopInterface; use React\Promise\Deferred; use React\Promise\PromiseInterface; +use RuntimeException; +use SoapFault; use function React\Promise\reject; use function React\Promise\resolve; class VsphereApi { - /** @var ServerInfo */ - protected $server; + protected ServerInfo $server; - /** @var LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; - /** @var CurlAsync */ - private $curl; + private CurlAsync $curl; /** @var SoapClient */ private $soapClient; - /** @var ManagedObjectReference */ - private $serviceInstanceRef; + private ManagedObjectReference $serviceInstanceRef; - private $initialWsdlFile; + private ?string $initialWsdlFile; /** @var ServiceContent */ private $serviceInstance; - /** @var CookieStore */ - private $cookieStore; + private CookieStore $cookieStore; - /** @var LoopInterface */ - private $loop; + private LoopInterface $loop; - /** @var ?ManagedObjectReference */ - private $eventCollector; + private ?ManagedObjectReference $eventCollector = null; - /** @var int */ - private $lastEventTimestamp; + private ?int $lastEventTimestamp = null; public function __construct( - $initialWsdlFile, + ?string $initialWsdlFile, ServerInfo $server, CurlAsync $curl, LoopInterface $loop, @@ -100,11 +95,7 @@ public function __construct( */ public function getServiceInstance(): PromiseInterface { - if ($this->serviceInstance === null) { - $this->serviceInstance = $this->retrieveServiceContent(); - } - - return resolve($this->serviceInstance); + return resolve($this->serviceInstance ??= $this->retrieveServiceContent()); } /** @@ -121,6 +112,7 @@ public function getCurrentTime(): PromiseInterface * Really fetch the ServiceInstance * * @return PromiseInterface + * * @see getServiceInstance() * */ @@ -156,6 +148,7 @@ public function eventuallyLogin(): PromiseInterface } $this->logger->notice($message); $this->cookieStore->forgetCookies(); + return $this->login(); }); } else { @@ -167,6 +160,7 @@ public function eventuallyLogin(): PromiseInterface * API login * * This will retrieve a session cookie and pass it with subsequent requests + * * @return PromiseInterface */ public function login(): PromiseInterface @@ -174,7 +168,7 @@ public function login(): PromiseInterface $this->logger->debug(sprintf('Sending Login request to %s', $this->makeLocation())); return $this->callOnServiceInstanceObject('sessionManager', 'Login', [ 'userName' => $this->server->get('username'), - 'password' => $this->server->get('password'), + 'password' => $this->server->get('password') ])->then(function ($result) { return $result->returnval; }); @@ -210,19 +204,23 @@ public function eventuallyLogout(): PromiseInterface /** * @param ManagedObjectReference $self - * @param $method + * @param string $method * @param array $arguments + * * @return PromiseInterface */ - public function call(ManagedObjectReference $self, $method, $arguments = []): PromiseInterface + public function call(ManagedObjectReference $self, string $method, array $arguments = []): PromiseInterface { return $this->soapClient->call($method, [[ '_this' => $self ] + $arguments]); } - public function callOnServiceInstanceObject($serviceInstanceObjectName, $method, $arguments = []) - { + public function callOnServiceInstanceObject( + string $serviceInstanceObjectName, + string $method, + array $arguments = [] + ): PromiseInterface { $property = $serviceInstanceObjectName; return $this->getServiceInstance() ->then(function (ServiceContent $serviceContent) use ($property, $method, $arguments) { @@ -231,7 +229,7 @@ public function callOnServiceInstanceObject($serviceInstanceObjectName, $method, } $ref = $serviceContent->$property; if (! $ref instanceof ManagedObjectReference) { - return reject(new \InvalidArgumentException( + return reject(new InvalidArgumentException( "ServiceContent.$property is no a ManagedObjectReference" )); } @@ -242,11 +240,14 @@ public function callOnServiceInstanceObject($serviceInstanceObjectName, $method, /** * @param ManagedObjectReference $object - * @param array|null $properties + * @param ?array $properties + * * @return PromiseInterface */ - public function requireSingleObjectProperties(ManagedObjectReference $object, $properties = null): PromiseInterface - { + public function requireSingleObjectProperties( + ManagedObjectReference $object, + ?array $properties = null + ): PromiseInterface { return $this->fetchSingleObject($object, $properties)->then(function ($resultObject) use ($object) { if ($resultObject) { return $resultObject; @@ -261,10 +262,11 @@ public function requireSingleObjectProperties(ManagedObjectReference $object, $p /** * @param ManagedObjectReference $object - * @param array|null $properties + * @param ?array $properties + * * @return PromiseInterface */ - public function fetchSingleObject(ManagedObjectReference $object, $properties = null): PromiseInterface + public function fetchSingleObject(ManagedObjectReference $object, ?array $properties = null): PromiseInterface { return $this->retrieveProperties([$this->singleObjectSpecSet($object, $properties)]) ->then(function (RetrieveResult $result) use ($object) { @@ -283,7 +285,7 @@ public function fetchSingleObject(ManagedObjectReference $object, $properties = }); } - public function fetchCustomFieldsManager() + public function fetchCustomFieldsManager(): PromiseInterface { return $this->getServiceInstance()->then(function (ServiceContent $serviceContent) { if (! isset($serviceContent->customFieldsManager)) { @@ -297,11 +299,14 @@ public function fetchCustomFieldsManager() /** * @param ManagedObjectReference $object - * @param array|null $properties + * @param ?array $properties + * * @return PromiseInterface */ - public function fetchSingleObjectProperties(ManagedObjectReference $object, $properties = null): PromiseInterface - { + public function fetchSingleObjectProperties( + ManagedObjectReference $object, + ?array $properties = null + ): PromiseInterface { return $this->retrieveProperties([$this->singleObjectSpecSet($object, $properties)]) ->then(function (RetrieveResult $result) use ($object) { if (empty($result->objects)) { @@ -314,6 +319,7 @@ public function fetchSingleObjectProperties(ManagedObjectReference $object, $pro $object->getLogName() ))); } + return $result->objects[0]; }); } @@ -321,6 +327,7 @@ public function fetchSingleObjectProperties(ManagedObjectReference $object, $pro * TODO: Can be used for mass requests once we deal with the token in the RetrieveResult * * @param PropertyFilterSpec[] $specSet + * * @return PromiseInterface */ public function retrieveProperties(array $specSet): PromiseInterface @@ -341,18 +348,19 @@ public function retrieveProperties(array $specSet): PromiseInterface } $result = new RetrieveResult(); $result->objects = $objects; + return $result; }); }); }); } - public function getCurrentSession() + public function getCurrentSession(): PromiseInterface { return $this->getServiceInstance()->then(function (ServiceContent $content) { return $this->fetchSingleObject($content->sessionManager, [ 'currentSession', - 'defaultLocale', + 'defaultLocale' ])->then(function (SessionManager $manager) { if (isset($manager->currentSession)) { return $manager->currentSession; @@ -386,10 +394,10 @@ public function fetchUniqueId(): PromiseInterface [PropertySpec::create('HostSystem', ['hardware.systemInfo.uuid'])] )])->then(function ($result) { if (empty($result)) { - throw new \RuntimeException('Unable to fetch host object for ESXi system'); + throw new RuntimeException('Unable to fetch host object for ESXi system'); } if (count($result) > 1) { - throw new \RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Expected to get one host from an ESXi system, got %d', count($result) )); @@ -398,7 +406,7 @@ public function fetchUniqueId(): PromiseInterface return Uuid::fromString($result[0]['hardware.systemInfo.uuid']); } - throw new \RuntimeException('Got no hardware.systemInfo.uuid from ESXi host'); + throw new RuntimeException('Got no hardware.systemInfo.uuid from ESXi host'); }); } else { return Uuid::fromString($content->about->instanceUuid); @@ -406,14 +414,14 @@ public function fetchUniqueId(): PromiseInterface }); } - public function setLastEventTimestamp($timestamp) + public function setLastEventTimestamp(?int $timestamp): static { $this->lastEventTimestamp = $timestamp; return $this; } - protected function fetchFullResult(RetrieveResult $result, &$objects) + protected function fetchFullResult(RetrieveResult $result, array &$objects): PromiseInterface { $deferred = new Deferred(); if ($result->hasMoreResults()) { @@ -437,7 +445,7 @@ protected function fetchFullResult(RetrieveResult $result, &$objects) return $deferred->promise(); } - protected function getPropertyCollector() + protected function getPropertyCollector(): PromiseInterface { return $this->getServiceInstance()->then(function (ServiceContent $serviceContent) { return $serviceContent->propertyCollector; @@ -458,7 +466,7 @@ protected function requireRetrieveResult($result) return $result; } - protected function continueFetchProperties($token) + protected function continueFetchProperties($token): PromiseInterface { return $this->callOnServiceInstanceObject('propertyCollector', 'ContinueRetrievePropertiesEx', [ 'token' => $token @@ -467,7 +475,7 @@ protected function continueFetchProperties($token) }); } - protected function singleObjectSpecSet(ManagedObjectReference $moRef, $properties = null) + protected function singleObjectSpecSet(ManagedObjectReference $moRef, ?array $properties = null): PropertyFilterSpec { return PropertyFilterSpec::create( [ObjectSpec::create($moRef, null, false)], @@ -475,7 +483,7 @@ protected function singleObjectSpecSet(ManagedObjectReference $moRef, $propertie ); } - protected function fetchSpecSet(array $specSet) + protected function fetchSpecSet(array $specSet): PromiseInterface { return $this->retrieveProperties($specSet)->then(function (RetrieveResult $result) { return $result->jsonSerialize(); @@ -483,12 +491,15 @@ protected function fetchSpecSet(array $specSet) } /** - * @param string|SelectSet $selectSetClass It's a string, SelectSet helps the IDE - * @param string|PropertySet $propertySetClass It's a string, PropertySet helps the IDE + * @param class-string $selectSetClass + * @param class-string $propertySetClass + * * @return PromiseInterface */ - public function fetchBySelectAndPropertySetClass($selectSetClass, $propertySetClass) - { + public function fetchBySelectAndPropertySetClass( + string $selectSetClass, + string $propertySetClass + ): PromiseInterface { return $this->getRootFolder()->then(function ($rootFolder) use ($selectSetClass, $propertySetClass) { return $this->fetchSpecSet([PropertyFilterSpec::create( [ObjectSpec::create($rootFolder, $selectSetClass::create(), false)], @@ -497,26 +508,26 @@ public function fetchBySelectAndPropertySetClass($selectSetClass, $propertySetCl }); } - public function readNextEvents() + public function readNextEvents(): PromiseInterface { return $this->callOnEventCollector('ReadNextEvents', [ - 'maxCount' => 1000, + 'maxCount' => 1000 ]); } - public function rewindEventCollector() + public function rewindEventCollector(): PromiseInterface { return $this->callOnEventCollector('RewindCollector'); } - public function fetchPerformanceManager() + public function fetchPerformanceManager(): PromiseInterface { return $this->getServiceInstance()->then(function (ServiceContent $serviceContent) { return $this->fetchSingleObject($serviceContent->perfManager); }); } - protected function getEventCollector() + protected function getEventCollector(): PromiseInterface|ManagedObjectReference { if ($this->eventCollector) { return resolve($this->eventCollector); @@ -531,11 +542,11 @@ protected function getEventCollector() }); } - throw new \RuntimeException('EventCollector reference expected, got ' . var_export($result, 1)); + throw new RuntimeException('EventCollector reference expected, got ' . var_export($result, 1)); }); } - protected function callOnEventCollector($method, $arguments = []) + protected function callOnEventCollector($method, $arguments = []): PromiseInterface { // Sample: // $collector = new ManagedObjectReference( @@ -550,12 +561,12 @@ protected function callOnEventCollector($method, $arguments = []) return []; }, function (Exception $e) { - if ($e instanceof \SoapFault) { + if ($e instanceof SoapFault) { if (isset($e->detail)) { $details = (array)$e->detail; if (current($details)->enc_stype === 'ManagedObjectNotFound') { $this->eventCollector = null; - throw new \RuntimeException( + throw new RuntimeException( 'Dropping formerly known EventCollector: ' . $e->getMessage(), $e->getCode(), $e @@ -568,7 +579,7 @@ protected function callOnEventCollector($method, $arguments = []) }); } - protected function createEventCollector($lastEventTimestamp = null) + protected function createEventCollector($lastEventTimestamp = null): PromiseInterface { $spec = new EventFilterSpec(); $spec->type = $this->getRequiredEventTypes(); @@ -584,7 +595,7 @@ protected function createEventCollector($lastEventTimestamp = null) /** * @throws Exception e.g.: SOAP-ERROR: Parsing Schema: can't import schema from '/tmp/[..]/vim-types.xsd */ - protected function prepareSoapClient() + protected function prepareSoapClient(): void { $this->soapClient = new SoapClient($this->curl, $this->initialWsdlFile, [ 'trace' => true, @@ -594,7 +605,7 @@ protected function prepareSoapClient() 'classmap' => ApiClassMap::getMap(), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS | SOAP_USE_XSI_ARRAY_TYPE, 'cache_wsdl' => WSDL_CACHE_NONE, - 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP, + 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP ], CurlOptions::forServerInfo($this->server), $this->logger); $this->soapClient->setCookieStore($this->cookieStore); } @@ -604,12 +615,12 @@ protected function prepareSoapClient() * * @return string */ - protected function makeLocation() + protected function makeLocation(): string { return $this->server->getUrl() . '/sdk'; } - protected function getRequiredEventTypes() + protected function getRequiredEventTypes(): array { return [ 'AlarmAcknowledgedEvent', @@ -642,7 +653,7 @@ protected function getRequiredEventTypes() 'VmBeingClonedEvent', 'VmBeingClonedNoFolderEvent', 'VmClonedEvent', - 'VmCloneFailedEvent', + 'VmCloneFailedEvent' ]; } } diff --git a/library/Vspheredb/Polling/WsdlLoader.php b/library/Vspheredb/Polling/WsdlLoader.php index dd9b2312..0c3fa7ac 100644 --- a/library/Vspheredb/Polling/WsdlLoader.php +++ b/library/Vspheredb/Polling/WsdlLoader.php @@ -28,7 +28,7 @@ class WsdlLoader * * @var array */ - protected $requiredFiles = [ + protected array $requiredFiles = [ 'vimService.wsdl', 'vim.wsdl', 'core-types.xsd', @@ -37,29 +37,27 @@ class WsdlLoader 'reflect-types.xsd', 'reflect-messagetypes.xsd', 'vim-types.xsd', - 'vim-messagetypes.xsd', + 'vim-messagetypes.xsd' ]; - protected $logger; + protected LoggerInterface $logger; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - protected $cacheDir; + protected string $cacheDir; - protected $curl; + protected CurlAsync $curl; - protected $serverInfo; + protected ServerInfo $serverInfo; - protected $baseUrl; + protected string $baseUrl; /** @var PromiseInterface[] */ - protected $pending = []; + protected array $pending = []; - /** @var ?Deferred */ - protected $deferred; + protected ?Deferred $deferred = null; - public function __construct($cacheDir, LoggerInterface $logger, ServerInfo $server, CurlAsync $curl) + public function __construct(string $cacheDir, LoggerInterface $logger, ServerInfo $server, CurlAsync $curl) { $this->cacheDir = $cacheDir; $this->logger = $logger; @@ -68,7 +66,7 @@ public function __construct($cacheDir, LoggerInterface $logger, ServerInfo $serv $this->baseUrl = $server->getUrl(); } - public function fetchInitialWsdlFile(LoopInterface $loop) + public function fetchInitialWsdlFile(LoopInterface $loop): PromiseInterface { $this->loop = $loop; return $this->fetchFiles()->then(function () { @@ -76,12 +74,12 @@ public function fetchInitialWsdlFile(LoopInterface $loop) }); } - protected function getInitialFilename() + protected function getInitialFilename(): string { return $this->cacheDir . '/' . $this->requiredFiles[0]; } - public function stop() + public function stop(): void { if ($this->deferred) { $deferred = $this->deferred; @@ -95,7 +93,7 @@ public function stop() } } - public function flushWsdlCache() + public function flushWsdlCache(): void { $dir = $this->cacheDir; $unlinked = false; @@ -147,10 +145,11 @@ protected function processFileFailure(Exception $e, string $file): void } } - protected function fetchFiles() + protected function fetchFiles(): PromiseInterface { if ($this->deferred) { $this->logger->notice('Calling WsdlLoader::fetchFiles while already loading'); + return $this->deferred->promise(); } $this->deferred = $deferred = new Deferred(); @@ -181,7 +180,7 @@ protected function fetchFiles() return $deferred->promise(); } - protected function resolveIfReady() + protected function resolveIfReady(): void { if (empty($this->pending)) { $deferred = $this->deferred; @@ -198,7 +197,7 @@ protected function resolveIfReady() } } - protected function url($file) + protected function url($file): string { return $this->baseUrl . "/sdk/$file"; } diff --git a/library/Vspheredb/ProvidedHook/Director/DataTypeMonitoringRule.php b/library/Vspheredb/ProvidedHook/Director/DataTypeMonitoringRule.php index 8693220a..60d1c800 100644 --- a/library/Vspheredb/ProvidedHook/Director/DataTypeMonitoringRule.php +++ b/library/Vspheredb/ProvidedHook/Director/DataTypeMonitoringRule.php @@ -5,12 +5,13 @@ use Icinga\Module\Director\Hook\DataTypeHook; use Icinga\Module\Director\Web\Form\QuickForm; use Icinga\Module\Vspheredb\Monitoring\Rule\Definition\RuleSetRegistry; +use Zend_Form_Element; class DataTypeMonitoringRule extends DataTypeHook { protected $db; - public function getFormElement($name, QuickForm $form) + public function getFormElement($name, QuickForm $form): Zend_Form_Element { $registry = RuleSetRegistry::default(); $options = []; @@ -26,7 +27,7 @@ public function getFormElement($name, QuickForm $form) $options[$set->getLabel()] = $current; } return $form->createElement('select', $name, [ - 'multiOptions' => ['' => $form->translate('- please choose -')] + $options, + 'multiOptions' => ['' => $form->translate('- please choose -')] + $options ]); } } diff --git a/library/Vspheredb/ProvidedHook/Director/ImportSource.php b/library/Vspheredb/ProvidedHook/Director/ImportSource.php index d52b751b..de739c9f 100644 --- a/library/Vspheredb/ProvidedHook/Director/ImportSource.php +++ b/library/Vspheredb/ProvidedHook/Director/ImportSource.php @@ -16,6 +16,7 @@ use Icinga\Module\Vspheredb\Web\Table\TableWithVCenterFilter; use Ramsey\Uuid\Uuid; use Zend_Db_Adapter_Abstract as ZfDb; +use Zend_Db_Select; use function array_keys; @@ -26,7 +27,7 @@ */ class ImportSource extends ImportSourceHook implements TableWithVCenterFilter, TableWithParentFilter { - protected $hostColumns = [ + protected array $hostColumns = [ 'object_name' => 'o.object_name', 'uuid' => 'o.uuid', 'parent_uuid' => 'o.parent_uuid', @@ -42,10 +43,10 @@ class ImportSource extends ImportSourceHook implements TableWithVCenterFilter, T 'custom_values' => 'h.custom_values', 'tags' => '(NULL)', 'internal_tags' => 'o.tags', - 'path' => '(NULL)', + 'path' => '(NULL)' ]; - protected $vmColumns = [ + protected array $vmColumns = [ 'object_name' => 'o.object_name', 'moref' => 'o.moref', 'uuid' => 'o.uuid', @@ -69,10 +70,10 @@ class ImportSource extends ImportSourceHook implements TableWithVCenterFilter, T 'tags' => '(NULL)', 'internal_tags' => 'o.tags', 'path' => '(NULL)', - 'resource_pool' => 'rp.object_name', + 'resource_pool' => 'rp.object_name' ]; - protected $computeResourceColumns = [ + protected array $computeResourceColumns = [ 'object_name' => 'o.object_name', 'object_type' => 'o.object_type', 'uuid' => 'o.uuid', @@ -88,10 +89,10 @@ class ImportSource extends ImportSourceHook implements TableWithVCenterFilter, T 'total_memory_size_mb' => 'cr.total_memory_size_mb', 'tags' => '(NULL)', 'internal_tags' => 'o.tags', - 'path' => '(NULL)', + 'path' => '(NULL)' ]; - protected $datastoreColumns = [ + protected array $datastoreColumns = [ 'object_name' => 'o.object_name', 'uuid' => 'o.uuid', 'parent_uuid' => 'o.parent_uuid', @@ -101,20 +102,18 @@ class ImportSource extends ImportSourceHook implements TableWithVCenterFilter, T 'multiple_host_access' => 'ds.multiple_host_access', 'tags' => '(NULL)', 'internal_tags' => 'o.tags', - 'path' => '(NULL)', + 'path' => '(NULL)' ]; - /** @var ?array */ - protected $parentFilterUuids = null; - /** @var ?array */ - protected $vCenterFilterUuids = null; + protected ?array $parentFilterUuids = null; + protected ?array $vCenterFilterUuids = null; - public function getName() + public function getName(): string { return 'VMware vSphereDB'; } - public static function addSettingsFormFields(QuickForm $form) + public static function addSettingsFormFields(QuickForm $form): void { assert($form instanceof ImportSourceForm); $form->addElement('select', 'object_type', [ @@ -123,35 +122,38 @@ public static function addSettingsFormFields(QuickForm $form) 'host_system' => mt('vspheredb', 'Host Systems'), 'virtual_machine' => mt('vspheredb', 'Virtual Machine'), 'compute_resource' => mt('vspheredb', 'Compute Resource'), - 'datastore' => mt('vspheredb', 'Datastore'), + 'datastore' => mt('vspheredb', 'Datastore') ]), 'class' => 'autosubmit', 'required' => true ]); $form->addElement('select', 'vcenter_uuid', [ 'label' => mt('vspheredb', 'vCenter'), - 'multiOptions' => ['' => mt('vspheredb', '- any -')] + self::enumVCenters(), + 'multiOptions' => ['' => mt('vspheredb', '- any -')] + self::enumVCenters() ]); $type = $form->getSentOrObjectSetting('object_type'); if ($type === 'virtual_machine') { $form->addBoolean('skip_powered_off', [ 'label' => mt('vspheredb', 'Skip powered off VMs'), - 'value' => 'n', + 'value' => 'n' ]); $form->addBoolean('skip_templates', [ 'label' => mt('vspheredb', 'Skip Templates'), - 'value' => 'y', + 'value' => 'y' ]); } } + /** + * @return array + */ protected static function enumVCenters(): array { $db = Db::newConfiguredInstance(); $pairs = $db->fetchPairs( $db->select()->from(['vc' => 'vcenter'], [ 'uuid' => 'LOWER(HEX(vc.instance_uuid))', - 'name' => "vc.name || ' (' || REPLACE(vc.api_name, 'VMware ', '') || ')'", + 'name' => "vc.name || ' (' || REPLACE(vc.api_name, 'VMware ', '') || ')'" ])->order('vc.name') ); $enum = []; @@ -162,7 +164,12 @@ protected static function enumVCenters(): array return $enum; } - protected function eventuallyFilterVCenter($query) + /** + * @param Zend_Db_Select $query + * + * @return Zend_Db_Select + */ + protected function eventuallyFilterVCenter(Zend_Db_Select $query): Zend_Db_Select { $vCenterUuid = $this->getSetting('vcenter_uuid'); if ($vCenterUuid !== null && strlen($vCenterUuid) > 0) { @@ -180,21 +187,15 @@ public function fetchData(): array $pathLookup = new BulkPathLookup($connection); $tagLookup = new TagLookup($connection); $objectType = $this->getSetting('object_type'); - switch ($objectType) { - case 'host_system': - $query = $this->prepareHostsQuery($db); - break; - case 'virtual_machine': - $query = $this->prepareVmQuery($db); - break; - case 'compute_resource': - $query = $this->prepareComputeResourceQuery($db); - break; - case 'datastore': - $query = $this->prepareDatastoreQuery($db); - break; - default: - return []; + $query = match ($objectType) { + 'host_system' => $this->prepareHostsQuery($db), + 'virtual_machine' => $this->prepareVmQuery($db), + 'compute_resource' => $this->prepareComputeResourceQuery($db), + 'datastore' => $this->prepareDatastoreQuery($db), + default => null + }; + if ($query === null) { + return []; } QueryHelper::applyOptionalVCenterFilter($db, $query, 'vc.instance_uuid', $this->vCenterFilterUuids); $this->applyOptionalParentFilter($query); @@ -216,7 +217,12 @@ public function fetchData(): array return $result; } - public static function convertDbRowToJsonData($row) + /** + * @param object $row + * + * @return void + */ + public static function convertDbRowToJsonData(object $row): void { $row->uuid = Uuid::fromBytes(DbUtil::binaryResult($row->uuid))->toString(); if (isset($row->custom_values)) { @@ -241,7 +247,12 @@ public static function convertDbRowToJsonData($row) } } - protected function prepareVmQuery(ZfDb $db) + /** + * @param ZfDb $db + * + * @return Zend_Db_Select + */ + protected function prepareVmQuery(ZfDb $db): Zend_Db_Select { $query = $db->select()->from(['o' => 'object'], $this->vmColumns) ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []) @@ -258,7 +269,12 @@ protected function prepareVmQuery(ZfDb $db) return $query; } - protected function prepareHostsQuery(ZfDb $db) + /** + * @param ZfDb $db + * + * @return Zend_Db_Select + */ + protected function prepareHostsQuery(ZfDb $db): Zend_Db_Select { return $db->select()->from(['o' => 'object'], $this->hostColumns)->join( ['h' => 'host_system'], @@ -267,7 +283,12 @@ protected function prepareHostsQuery(ZfDb $db) )->order('o.object_name')->order('o.uuid'); } - protected function prepareComputeResourceQuery(ZfDb $db) + /** + * @param ZfDb $db + * + * @return Zend_Db_Select + */ + protected function prepareComputeResourceQuery(ZfDb $db): Zend_Db_Select { return $db->select()->from(['o' => 'object'], $this->computeResourceColumns)->join( ['cr' => 'compute_resource'], @@ -276,7 +297,12 @@ protected function prepareComputeResourceQuery(ZfDb $db) )->order('o.object_name')->order('o.uuid'); } - protected function prepareDatastoreQuery(ZfDb $db) + /** + * @param ZfDb $db + * + * @return Zend_Db_Select + */ + protected function prepareDatastoreQuery(ZfDb $db): Zend_Db_Select { return $db->select()->from(['o' => 'object'], $this->datastoreColumns)->join( ['ds' => 'datastore'], @@ -285,7 +311,12 @@ protected function prepareDatastoreQuery(ZfDb $db) )->order('o.object_name')->order('o.uuid'); } - protected function joinVCenter($query) + /** + * @param Zend_Db_Select $query + * + * @return Zend_Db_Select + */ + protected function joinVCenter(Zend_Db_Select $query): Zend_Db_Select { return $query->join( ['vc' => 'vcenter'], @@ -296,29 +327,31 @@ protected function joinVCenter($query) public function listColumns(): array { - switch ($this->getSetting('object_type')) { - case 'host_system': - return array_keys($this->hostColumns); - case 'virtual_machine': - return array_keys($this->vmColumns); - case 'compute_resource': - return array_keys($this->computeResourceColumns); - case 'datastore': - return array_keys($this->datastoreColumns); - default: - return []; - } + return match ($this->getSetting('object_type')) { + 'host_system' => array_keys($this->hostColumns), + 'virtual_machine' => array_keys($this->vmColumns), + 'compute_resource' => array_keys($this->computeResourceColumns), + 'datastore' => array_keys($this->datastoreColumns), + default => [] + }; // Alternative: return $this->callOnManagedObject('getDefaultPropertySet'); } + /** + * @return string + */ protected function getManagedObjectClass(): string { - return 'Icinga\\Module\\Vspheredb\\DbObject\\' - . $this->getSetting('object_type'); + return 'Icinga\\Module\\Vspheredb\\DbObject\\' . $this->getSetting('object_type'); } - protected function callOnManagedObject($method) + /** + * @param string $method + * + * @return mixed + */ + protected function callOnManagedObject(string $method): mixed { $params = func_get_args(); array_shift($params); @@ -337,23 +370,41 @@ public static function getDefaultKeyColumnName(): ?string return 'object_name'; } - public function filterVCenter(VCenter $vCenter): self + public function filterVCenter(VCenter $vCenter): static { return $this->filterVCenterUuids([$vCenter->getUuid()]); } - public function filterVCenterUuids(?array $uuids): self + /** + * @param ?array $uuids + * + * @return $this + */ + public function filterVCenterUuids(?array $uuids): static { $this->vCenterFilterUuids = $uuids; + return $this; } - public function filterParentUuids(?array $uuids) + /** + * @param ?array $uuids + * + * @return $this + */ + public function filterParentUuids(?array $uuids): static { $this->parentFilterUuids = $uuids; + + return $this; } - protected function applyOptionalParentFilter($query) + /** + * @param $query + * + * @return void + */ + protected function applyOptionalParentFilter($query): void { if ($this->parentFilterUuids === null) { return; diff --git a/library/Vspheredb/ProvidedHook/HostDetailExtensionTrait.php b/library/Vspheredb/ProvidedHook/HostDetailExtensionTrait.php index 2fa3b1ef..10f6b523 100644 --- a/library/Vspheredb/ProvidedHook/HostDetailExtensionTrait.php +++ b/library/Vspheredb/ProvidedHook/HostDetailExtensionTrait.php @@ -26,9 +26,9 @@ trait HostDetailExtensionTrait { use Translation; - protected Db $db; + protected ?Db $db = null; - protected CheckRelatedLookup $lookup; + protected ?CheckRelatedLookup $lookup = null; /** * @param object $host @@ -38,7 +38,7 @@ trait HostDetailExtensionTrait */ abstract protected function getCustomVar(object $host, string $customVar): ?string; - public function init() + public function init(): void { $this->db = Db::newConfiguredInstance(); $this->lookup = new CheckRelatedLookup($this->db); @@ -49,7 +49,7 @@ public function init() * * @return ValidHtml */ - public function renderVObject($vObject): ValidHtml + public function renderVObject(VirtualMachine|HostSystem $vObject): ValidHtml { $container = new HtmlElement('div', new Attributes([ 'class' => [ @@ -71,6 +71,11 @@ public function renderVObject($vObject): ValidHtml return $container; } + /** + * @param HostSystem $host + * + * @return ValidHtml + */ protected function renderHostSystem(HostSystem $host): ValidHtml { $stats = HostQuickStats::loadFor($host); @@ -92,6 +97,11 @@ protected function renderHostSystem(HostSystem $host): ValidHtml )); } + /** + * @param VirtualMachine $vm + * + * @return ValidHtml + */ protected function renderVirtualMachine(VirtualMachine $vm): ValidHtml { $stats = VmQuickStats::loadFor($vm); @@ -123,7 +133,7 @@ protected function renderVirtualMachine(VirtualMachine $vm): ValidHtml * * @return HostSystem|VirtualMachine|null */ - protected function find(object $host, string $sourceType) + protected function find(object $host, string $sourceType): VirtualMachine|HostSystem|null { $spec = [ 'HostSystem' => ['host', 'host_system', 'host'], @@ -145,11 +155,10 @@ protected function find(object $host, string $sourceType) continue; } - if (substr($property, 0, 5) === 'vars.') { - $value = $this->getCustomVar($host, substr($property, 5)); - } else { - $value = $host->$property; - } + $value = str_starts_with($property, 'vars.') + ? $this->getCustomVar($host, substr($property, 5)) + : $host->$property; + if (! $value) { continue; } @@ -162,7 +171,7 @@ protected function find(object $host, string $sourceType) try { $object = $this->lookup->findOneBy($type, $filter); assert($object instanceof HostSystem || $object instanceof VirtualMachine); - } catch (NotFoundError $_) { + } catch (NotFoundError) { continue; } diff --git a/library/Vspheredb/ProvidedHook/Monitoring/DetailviewExtension.php b/library/Vspheredb/ProvidedHook/Monitoring/DetailviewExtension.php index b0752ee3..6cd3f51c 100644 --- a/library/Vspheredb/ProvidedHook/Monitoring/DetailviewExtension.php +++ b/library/Vspheredb/ProvidedHook/Monitoring/DetailviewExtension.php @@ -12,6 +12,11 @@ class DetailviewExtension extends DetailviewExtensionHook { use HostDetailExtensionTrait; + /** + * @param MonitoredObject $object + * + * @return ?ValidHtml + */ public function getHtmlForObject(MonitoredObject $object): ?ValidHtml { if (! $object instanceof Host) { diff --git a/library/Vspheredb/ProvidedHook/Vspheredb/PerfDataConsumerInfluxDb.php b/library/Vspheredb/ProvidedHook/Vspheredb/PerfDataConsumerInfluxDb.php index 250cf595..33fe4f86 100644 --- a/library/Vspheredb/ProvidedHook/Vspheredb/PerfDataConsumerInfluxDb.php +++ b/library/Vspheredb/ProvidedHook/Vspheredb/PerfDataConsumerInfluxDb.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\ProvidedHook\Vspheredb; +use gipfl\Web\Form; use Icinga\Module\Vspheredb\Daemon\RemoteClient; use Icinga\Module\Vspheredb\Hook\PerfDataConsumerHook; use Icinga\Module\Vspheredb\Web\Form\ChooseInfluxDatabaseForm; @@ -9,17 +10,17 @@ class PerfDataConsumerInfluxDb extends PerfDataConsumerHook { - public static function getName() + public static function getName(): string { return 'InfluxDB'; } - public function getConfigurationForm(RemoteClient $client) + public function getConfigurationForm(RemoteClient $client): Form { return new InfluxDbConnectionForm($this->loop, $client); } - public function getSubscriptionForm(RemoteClient $client) + public function getSubscriptionForm(RemoteClient $client): Form { return new ChooseInfluxDatabaseForm($this->loop, $client, $this); } diff --git a/library/Vspheredb/SafeCacheDir.php b/library/Vspheredb/SafeCacheDir.php index 0ff5d3c3..455735f2 100644 --- a/library/Vspheredb/SafeCacheDir.php +++ b/library/Vspheredb/SafeCacheDir.php @@ -6,30 +6,25 @@ class SafeCacheDir { - protected static $currentUser; + protected static ?string $currentUser = null; /** * @return string */ - public static function getDirectory() + public static function getDirectory(): string { - $directory = sprintf( - '%s/%s-%s', - sys_get_temp_dir(), - 'iwebVsphere', - static::getCurrentUsername() - ); - + $directory = sprintf('%s/%s-%s', sys_get_temp_dir(), 'iwebVsphere', static::getCurrentUsername()); static::claimDirectory($directory); return $directory; } /** - * @param $directory + * @param string $directory + * * @return string */ - public static function getSubDirectory($directory) + public static function getSubDirectory(string $directory): string { $subDir = static::getDirectory() . "/$directory"; static::claimDirectory($subDir); @@ -38,9 +33,9 @@ public static function getSubDirectory($directory) } /** - * @param $directory + * @param string $directory */ - protected static function claimDirectory($directory) + protected static function claimDirectory(string $directory): void { if (file_exists($directory)) { if (static::uidToName(fileowner($directory)) !== static::getCurrentUsername()) { @@ -52,35 +47,31 @@ protected static function claimDirectory($directory) } } else { if (! @mkdir($directory, 0700)) { - throw new RuntimeException(sprintf( - 'Could not create %s', - $directory - )); + throw new RuntimeException(sprintf('Could not create %s', $directory)); } } } /** - * @return mixed + * @return string */ - protected static function getCurrentUsername() + protected static function getCurrentUsername(): string { if (static::$currentUser === null) { if (function_exists('posix_geteuid')) { static::$currentUser = static::uidToName(posix_geteuid()); } else { - throw new RuntimeException( - 'POSIX methods not available, is php-posix installed and enabled?' - ); + throw new RuntimeException('POSIX methods not available, is php-posix installed and enabled?'); } } return static::$currentUser; } - protected static function uidToName($uid) + protected static function uidToName(int $uid): string { $info = posix_getpwuid($uid); + return $info['name']; } } diff --git a/library/Vspheredb/Severity.php b/library/Vspheredb/Severity.php index 81127ae8..fc44c18a 100644 --- a/library/Vspheredb/Severity.php +++ b/library/Vspheredb/Severity.php @@ -9,13 +9,13 @@ class Severity protected static $colorToStateMap = [ 'green' => 'Normal', 'yellow' => 'Warning', - 'red' => 'Alert', + 'red' => 'Alert' ]; protected static $stateToColorMap = [ 'Normal' => 'green', 'Warning' => 'yellow', - 'Alert' => 'red', + 'Alert' => 'red' ]; /** @@ -29,9 +29,9 @@ public static function colorToSeverity(string $color): string { if (array_key_exists($color, self::$colorToStateMap)) { return self::$colorToStateMap[$color]; - } else { - throw new ProgrammingError('Color expected, got "%s"', $color); } + + throw new ProgrammingError('Color expected, got "%s"', $color); } /** @@ -45,8 +45,8 @@ public static function severityToColor(string $severity): string { if (array_key_exists($severity, self::$stateToColorMap)) { return self::$stateToColorMap[$severity]; - } else { - throw new ProgrammingError('Severity expected, got "%s"', $severity); } + + throw new ProgrammingError('Severity expected, got "%s"', $severity); } } diff --git a/library/Vspheredb/Storable/PerfdataConsumer.php b/library/Vspheredb/Storable/PerfdataConsumer.php index 38a80373..c821b4f1 100644 --- a/library/Vspheredb/Storable/PerfdataConsumer.php +++ b/library/Vspheredb/Storable/PerfdataConsumer.php @@ -10,19 +10,19 @@ class PerfdataConsumer implements DbStorableInterface { use DbStorable; - protected $tableName = 'perfdata_consumer'; + protected string $tableName = 'perfdata_consumer'; - protected $keyProperty = 'uuid'; + protected string $keyProperty = 'uuid'; - protected $defaultProperties = [ + protected array $defaultProperties = [ 'uuid' => null, 'name' => null, 'implementation' => null, 'settings' => null, - 'enabled' => null, + 'enabled' => null ]; - public function settings() + public function settings(): mixed { $settings = $this->get('settings'); if ($settings === null) { diff --git a/library/Vspheredb/Storable/PerfdataSubscription.php b/library/Vspheredb/Storable/PerfdataSubscription.php index 3874abbd..55c7b21d 100644 --- a/library/Vspheredb/Storable/PerfdataSubscription.php +++ b/library/Vspheredb/Storable/PerfdataSubscription.php @@ -8,6 +8,7 @@ use gipfl\ZfDbStore\ZfDbStore; use Icinga\Module\Vspheredb\DbObject\VCenter; use Ramsey\Uuid\Uuid; +use RuntimeException; class PerfdataSubscription implements DbStorableInterface { @@ -15,19 +16,19 @@ class PerfdataSubscription implements DbStorableInterface set as parentSet; } - protected $tableName = 'perfdata_subscription'; + protected string $tableName = 'perfdata_subscription'; - protected $keyProperty = 'uuid'; + protected string $keyProperty = 'uuid'; - protected $defaultProperties = [ + protected array $defaultProperties = [ 'uuid' => null, 'consumer_uuid' => null, 'vcenter_uuid' => null, 'settings' => null, - 'enabled' => null, + 'enabled' => null ]; - public function set($property, $value) + public function set($property, $value): bool { if ($property === 'consumer') { $property = 'consumer_uuid'; @@ -49,7 +50,8 @@ public function settings() /** * @param VCenter $vCenter - * @return PerfdataSubscription|null + * + * @return ?PerfdataSubscription */ public static function optionallyLoadForVCenter(VCenter $vCenter, ZfDbStore $store) { @@ -64,7 +66,7 @@ public static function optionallyLoadForVCenter(VCenter $vCenter, ZfDbStore $sto } if (count($uuids) > 1) { - throw new \RuntimeException('More then one consumer per vCenter is currently not supported'); + throw new RuntimeException('More then one consumer per vCenter is currently not supported'); } return static::load($store, $uuids[0]); diff --git a/library/Vspheredb/SyncRelated/SyncHelper.php b/library/Vspheredb/SyncRelated/SyncHelper.php index f5fdb826..8935473e 100644 --- a/library/Vspheredb/SyncRelated/SyncHelper.php +++ b/library/Vspheredb/SyncRelated/SyncHelper.php @@ -3,18 +3,18 @@ namespace Icinga\Module\Vspheredb\SyncRelated; use Exception; -use gipfl\ZfDb\Adapter\Adapter; use Icinga\Module\Vspheredb\Db\DbObject; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use Icinga\Module\Vspheredb\DbObject\VCenter; +use Zend_Db_Adapter_Abstract; trait SyncHelper { /** - * @param \Zend_Db_Adapter_Abstract $db - * @param $callback + * @param Zend_Db_Adapter_Abstract $db + * @param callable $callback */ - protected static function runAsTransaction($db, $callback) + protected static function runAsTransaction(Zend_Db_Adapter_Abstract $db, callable $callback): void { $db->beginTransaction(); try { @@ -32,13 +32,21 @@ protected static function runAsTransaction($db, $callback) } /** - * @param Adapter|\Zend_Db_Adapter_Abstract $db + * @param Zend_Db_Adapter_Abstract $db * @param DbObject[] $dbObjects * @param array $apiObjects * @param SyncStats $stats + * + * @return void + * + * @throws Exception */ - protected function storeSyncObjects($db, array $dbObjects, array $apiObjects, SyncStats $stats) - { + protected function storeSyncObjects( + Zend_Db_Adapter_Abstract $db, + array $dbObjects, + array $apiObjects, + SyncStats $stats + ): void { $create = []; self::runAsTransaction($db, function () use ($apiObjects, &$dbObjects, $stats, &$create) { $modify = []; @@ -73,14 +81,16 @@ protected function storeSyncObjects($db, array $dbObjects, array $apiObjects, Sy } /** - * @param string $class + * @param class-string $class * @param string $table * @param VCenter $vCenter + * + * @return array + * * @return BaseDbObject[] */ - protected static function loadAllForVCenter($class, $table, VCenter $vCenter) + protected static function loadAllForVCenter(string $class, string $table, VCenter $vCenter): array { - /** @var string|BaseDbObject $class */ return $class::loadAll( $vCenter->getConnection(), $vCenter->getDb() diff --git a/library/Vspheredb/SyncRelated/SyncStats.php b/library/Vspheredb/SyncRelated/SyncStats.php index 24432df3..5f8d2ec5 100644 --- a/library/Vspheredb/SyncRelated/SyncStats.php +++ b/library/Vspheredb/SyncRelated/SyncStats.php @@ -3,52 +3,58 @@ namespace Icinga\Module\Vspheredb\SyncRelated; use gipfl\Json\JsonSerialization; +use ReturnTypeWillChange; class SyncStats implements JsonSerialization { - protected $created = 0; - protected $modified = 0; - protected $deleted = 0; - protected $totalFromApi = 0; - protected $totalFromDb = 0; - protected $label; - - public function __construct($label) + protected int $created = 0; + + protected int $modified = 0; + + protected int $deleted = 0; + + protected int $totalFromApi = 0; + + protected int $totalFromDb = 0; + + protected string $label; + + public function __construct(string $label) { $this->label = $label; } - public function setFromApi($count) + public function setFromApi($count): void { $this->totalFromApi = $count; } - public function setFromDb($count) + public function setFromDb($count): void { $this->totalFromDb = $count; } - public function incCreated($count = 1) + public function incCreated($count = 1): void { $this->created += $count; } - public function incModified($count = 1) + public function incModified($count = 1): void { $this->modified += $count; } - public function incDeleted($count = 1) + public function incDeleted($count = 1): void { $this->deleted += $count; } - public function hasChanges() + public function hasChanges(): bool { return $this->created > 0 || $this->modified > 0 || $this->deleted > 0; } - public function getLogMessage() + public function getLogMessage(): string { return sprintf( "%s: %d new, %d modified, %d deleted (got %d from DB, %d from API)", @@ -61,7 +67,7 @@ public function getLogMessage() ); } - public static function fromSerialization($any) + public static function fromSerialization($any): static { $self = new static($any->label); $self->created = $any->created; @@ -73,8 +79,11 @@ public static function fromSerialization($any) return $self; } - #[\ReturnTypeWillChange] - public function jsonSerialize() + #[ReturnTypeWillChange] + /** + * @return object + */ + public function jsonSerialize(): object { return (object) [ 'label' => $this->label, @@ -82,7 +91,7 @@ public function jsonSerialize() 'modified' => $this->modified, 'deleted' => $this->deleted, 'totalFromApi' => $this->totalFromApi, - 'totalFromDb' => $this->totalFromDb, + 'totalFromDb' => $this->totalFromDb ]; } } diff --git a/library/Vspheredb/Util.php b/library/Vspheredb/Util.php index efd25b39..2031f0ac 100644 --- a/library/Vspheredb/Util.php +++ b/library/Vspheredb/Util.php @@ -12,31 +12,31 @@ class Util * * @return int */ - public static function currentTimestamp() + public static function currentTimestamp(): int { $time = explode(' ', microtime()); return (int) round(1000 * ((int) $time[1] + (float) $time[0])); } - public static function timeStringToUnixTime($string) + public static function timeStringToUnixTime(string $string): int { return (new DateTime($string))->getTimestamp(); } - public static function timeStringToUnixMs($string) + public static function timeStringToUnixMs(string $string): int { - $time = new DateTime($string); - - return (int) (1000 * $time->format('U.u')); + return (int) (1000 * (new DateTime($string))->format('U.u')); } /** * DateTime for SOAP call - * @param $timestamp + * + * @param int $timestamp + * * @return string */ - public static function makeDateTime($timestamp) + public static function makeDateTime(int $timestamp): string { return gmdate('Y-m-d\TH:i:s\Z', $timestamp); } diff --git a/library/Vspheredb/VmwareDataType/ManagedObjectReference.php b/library/Vspheredb/VmwareDataType/ManagedObjectReference.php index 68e9be95..b4583afa 100644 --- a/library/Vspheredb/VmwareDataType/ManagedObjectReference.php +++ b/library/Vspheredb/VmwareDataType/ManagedObjectReference.php @@ -3,37 +3,41 @@ namespace Icinga\Module\Vspheredb\VmwareDataType; use gipfl\Json\JsonSerialization; +use ReturnTypeWillChange; /** * #[AllowDynamicProperties] */ class ManagedObjectReference implements JsonSerialization { - public $_; // phpcs:ignore + public string $_; // phpcs:ignore - public $type; + public string $type; - public function __construct($type, $moref) + public function __construct(string $type, string $moref) { $this->_ = $moref; $this->type = $type; } - public function getLogName() + public function getLogName(): string { return $this->type . '[' . $this->_ . ']'; } - #[\ReturnTypeWillChange] - public function jsonSerialize() + #[ReturnTypeWillChange] + /** + * @return object + */ + public function jsonSerialize(): object { return (object) [ '_' => $this->_, - 'type' => $this->type, + 'type' => $this->type ]; } - public static function fromSerialization($any) + public static function fromSerialization($any): static { return new static($any->type, $any->_); } diff --git a/library/Vspheredb/VmwareDataType/NumericRange.php b/library/Vspheredb/VmwareDataType/NumericRange.php index 2e906a39..a98adc4c 100644 --- a/library/Vspheredb/VmwareDataType/NumericRange.php +++ b/library/Vspheredb/VmwareDataType/NumericRange.php @@ -8,5 +8,6 @@ class NumericRange { public $start; + public $end; } diff --git a/library/Vspheredb/Web/Controller.php b/library/Vspheredb/Web/Controller.php index 049e26a7..3324bbcb 100644 --- a/library/Vspheredb/Web/Controller.php +++ b/library/Vspheredb/Web/Controller.php @@ -9,22 +9,18 @@ use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Util\Csp; +use ipl\Html\Attributes; use Zend_Controller_Request_Abstract as ZfRequest; use Zend_Controller_Response_Abstract as ZfResponse; class Controller extends CompatController { - /** @var Db */ - private $db; + private ?Db $db = null; - /** @var ?RestrictionHelper */ - private $restrictionHelper; + private ?RestrictionHelper $restrictionHelper = null; - public function __construct( - ZfRequest $request, - ZfResponse $response, - array $invokeArgs = array() - ) { + public function __construct(ZfRequest $request, ZfResponse $response, array $invokeArgs = array()) + { parent::__construct($request, $response, $invokeArgs); if (! $this->isXhr() && Config::app()->get('security', 'use_strict_csp', false)) { @@ -32,17 +28,15 @@ public function __construct( } } - public function init() + public function init(): void { parent::init(); if ($this->view->compact) { - $this->controls()->addAttributes([ - 'class' => 'show-compact' - ]); + $this->controls()->addAttributes(Attributes::create(['class' => 'show-compact'])); } } - protected function db() + protected function db(): Db { if ($this->db === null) { try { @@ -51,7 +45,7 @@ protected function db() if (! $migrations->hasSchema()) { $this->redirectToConfiguration(); } - } catch (Exception $e) { + } catch (Exception) { $this->redirectToConfiguration(); } } @@ -61,21 +55,18 @@ protected function db() protected function getRestrictionHelper(): RestrictionHelper { - if ($this->restrictionHelper === null) { - $this->restrictionHelper = new RestrictionHelper($this->Auth(), $this->db()); - } - - return $this->restrictionHelper; + return $this->restrictionHelper ??= new RestrictionHelper($this->Auth(), $this->db()); } protected function requireVCenter($paramName = 'vcenter'): VCenter { $vCenter = VCenter::loadWithUuid($this->params->getRequired($paramName), $this->db()); $this->getRestrictionHelper()->assertAccessToVCenterUuidIsGranted($vCenter->get('instance_uuid')); + return $vCenter; } - protected function redirectToConfiguration() + protected function redirectToConfiguration(): void { if ( $this->getRequest()->getControllerName() !== 'configuration' diff --git a/library/Vspheredb/Web/Controller/ObjectsController.php b/library/Vspheredb/Web/Controller/ObjectsController.php index a1b122a8..9ef93236 100644 --- a/library/Vspheredb/Web/Controller/ObjectsController.php +++ b/library/Vspheredb/Web/Controller/ObjectsController.php @@ -13,6 +13,7 @@ use Icinga\Module\Vspheredb\Web\Table\Objects\ObjectsTable; use Icinga\Module\Vspheredb\Web\Table\TableWithParentFilter; use Icinga\Module\Vspheredb\Web\Table\TableWithVCenterFilter; +use Icinga\Web\Url as WebUrl; use ipl\Html\Html; use Ramsey\Uuid\Uuid; @@ -20,13 +21,13 @@ class ObjectsController extends Controller { use RestApi; - protected $otherTabActions = []; + protected array $otherTabActions = []; - /** @var PathLookup */ - protected $pathLookup; - protected $vCenterFilterForm; + protected ?PathLookup $pathLookup = null; - protected function linkBackToOverview($type) + protected ?FilterVCenterForm $vCenterFilterForm = null; + + protected function linkBackToOverview($type): static { $this->actions()->add( Link::create( @@ -43,7 +44,7 @@ protected function linkBackToOverview($type) return $this; } - protected function addTreeViewToggle() + protected function addTreeViewToggle(): void { if ($this->params->get('render') === 'tree') { $this->actions()->add( @@ -66,12 +67,13 @@ protected function addTreeViewToggle() } } - protected function eventuallyFilterByParent(TableWithParentFilter $table, $url, $defaultTitle = null) - { - $parent = $this->params->get('parent'); - if ($parent === null) { - $parent = $this->params->get('uuid'); - } + protected function eventuallyFilterByParent( + TableWithParentFilter $table, + WebUrl|string $url, + ?string $defaultTitle = null + ): void { + $parent = $this->params->get('parent') ?? $this->params->get('uuid'); + if ($parent !== null) { $parent = Uuid::fromString($parent)->getBytes(); } @@ -79,11 +81,7 @@ protected function eventuallyFilterByParent(TableWithParentFilter $table, $url, if ($parent) { $lookup = $this->pathLookup(); $name = $lookup->getObjectName($parent); - if ($name) { - $this->addTitle($name); - } else { - $this->addTitle($defaultTitle); - } + $this->addTitle($name ?: $defaultTitle); if ($this->params->get('showDescendants')) { $uuids = $lookup->listFoldersBelongingTo($parent); $table->filterParentUuids($uuids); @@ -96,7 +94,7 @@ protected function eventuallyFilterByParent(TableWithParentFilter $table, $url, } } - protected function eventuallyFilterByVCenter(TableWithVCenterFilter $table) + protected function eventuallyFilterByVCenter(TableWithVCenterFilter $table): void { $this->getRestrictionHelper()->restrictTable($table); $this->getVCenterFilterForm(); @@ -119,7 +117,7 @@ protected function getVCenterFilterForm(): FilterVCenterForm return $this->vCenterFilterForm; } - protected function showTable(ObjectsTable $table, $url, $defaultTitle = null) + protected function showTable(ObjectsTable $table, WebUrl|string $url, ?string $defaultTitle = null): static { $this->eventuallyFilterByParent($table, $url, $defaultTitle); $this->eventuallyFilterByVCenter($table); @@ -129,7 +127,7 @@ protected function showTable(ObjectsTable $table, $url, $defaultTitle = null) return $this; } - protected function renderTableWithCount(ObjectsTable $table, $title = null) + protected function renderTableWithCount(ObjectsTable $table, ?string $title = null): void { $total = count($table); $table->renderTo($this); @@ -137,14 +135,14 @@ protected function renderTableWithCount(ObjectsTable $table, $title = null) return; } $found = count($table); - if ($total === $found) { - $this->content()->prepend(sprintf('%d %s', $total, $title)); - } else { - $this->content()->prepend(sprintf('%d out of %d %s', $found, $total, $title)); - } + $this->content()->prepend( + $total === $found + ? sprintf('%d %s', $total, $title) + : sprintf('%d out of %d %s', $found, $total, $title) + ); } - protected function downloadTable(ObjectsTable $table, string $title) + protected function downloadTable(ObjectsTable $table, string $title): void { $this->eventuallyFilterByParent($table, Url::fromPath(''), $title); $this->eventuallyFilterByVCenter($table); @@ -156,7 +154,7 @@ protected function downloadTable(ObjectsTable $table, string $title) $this->downloadJson($this->getResponse(), $rows, "$title.json"); } - protected function sendExport($type) + protected function sendExport($type): void { $import = new ImportSource(); $import->setSettings([ @@ -167,7 +165,7 @@ protected function sendExport($type) $this->downloadJson($this->getResponse(), $import->fetchData(), $type . 's.json'); } - protected function addPathTo($parent, $url) + protected function addPathTo(string $parent, WebUrl|string $url): void { $lookup = $this->pathLookup(); $path = Html::tag('span', ['class' => 'dc-path']); @@ -180,14 +178,14 @@ protected function addPathTo($parent, $url) } $path->add(Link::create($name, $url, [ 'parent' => Util::niceUuid($uuid), - 'showDescendants' => true, + 'showDescendants' => true ])); } $this->content()->add($path); } - protected function handleTabs() + protected function handleTabs(): void { $action = $this->getRequest()->getControllerName(); if (isset($this->otherTabActions[$action])) { @@ -198,15 +196,15 @@ protected function handleTabs() $this->tabs()->add('vms', [ 'label' => $this->translate('Virtual Machine'), 'url' => 'vspheredb/vms', - 'urlParams' => $urlParams, + 'urlParams' => $urlParams ])->add('hosts', [ 'label' => $this->translate('Hosts'), 'url' => 'vspheredb/hosts', - 'urlParams' => $urlParams, + 'urlParams' => $urlParams ])->add('datastores', [ 'label' => $this->translate('Datastores'), 'url' => 'vspheredb/datastores', - 'urlParams' => $urlParams, + 'urlParams' => $urlParams ]) // ->add('switches', [ // 'label' => $this->translate('Switches'), @@ -229,10 +227,6 @@ protected function getParentParamsToPreserve(): array protected function pathLookup(): PathLookup { - if ($this->pathLookup === null) { - $this->pathLookup = new PathLookup($this->db()->getDbAdapter()); - } - - return $this->pathLookup; + return $this->pathLookup ??= new PathLookup($this->db()->getDbAdapter()); } } diff --git a/library/Vspheredb/Web/Controller/RestApi.php b/library/Vspheredb/Web/Controller/RestApi.php index ef9936c7..c37e9eda 100644 --- a/library/Vspheredb/Web/Controller/RestApi.php +++ b/library/Vspheredb/Web/Controller/RestApi.php @@ -10,7 +10,7 @@ trait RestApi { - protected function downloadJson(Response $response, $object, $filename) + protected function downloadJson(Response $response, array|object $object, string $filename): void { if (!$this->hasPermission('vspheredb/export')) { $this->sendJsonError($this->getResponse(), 'vspheredb/export permissions required', 403); @@ -22,7 +22,7 @@ protected function downloadJson(Response $response, $object, $filename) $this->sendJson($response, $object); } - protected function sendJson(Response $response, $object) + protected function sendJson(Response $response, array|object $object): void { $response->setHeader('Content-Type', 'application/json', true); $this->_helper->layout()->disableLayout(); @@ -37,13 +37,15 @@ protected function sendJson(Response $response, $object) /** * @param Response $response * @param string $message - * @param int|null $code + * @param ?int $code + * + * @return void */ - protected function sendJsonError(Response $response, $message, $code = null) + protected function sendJsonError(Response $response, string $message, ?int $code = null): void { if ($code !== null) { try { - $response->setHttpResponseCode((int) $code); + $response->setHttpResponseCode($code); } catch (Zend_Controller_Response_Exception $e) { throw new InvalidArgumentException($e->getMessage(), 0, $e); } diff --git a/library/Vspheredb/Web/Form/ApplyMigrationsForm.php b/library/Vspheredb/Web/Form/ApplyMigrationsForm.php index 3a6c40dd..1d40746f 100644 --- a/library/Vspheredb/Web/Form/ApplyMigrationsForm.php +++ b/library/Vspheredb/Web/Form/ApplyMigrationsForm.php @@ -12,40 +12,30 @@ class ApplyMigrationsForm extends Form { use Translation; - /** @var Migrations */ - protected $migrations; + protected Migrations $migrations; public function __construct(Migrations $migrations) { $this->migrations = $migrations; } - public function assemble() + protected function assemble(): void { if ($this->migrations->hasSchema()) { $count = $this->migrations->countPendingMigrations(); - if ($count === 1) { - $label = $this->translate('Apply a pending schema migration'); - } else { - $label = sprintf( - $this->translate('Apply %d pending schema migrations'), - $count - ); - } + $label = $count === 1 + ? $this->translate('Apply a pending schema migration') + : sprintf($this->translate('Apply %d pending schema migrations'), $count); } else { $this->add(Hint::warning($this->translate('There is no vSphereDB schema in this database'))); $label = $this->translate('Create schema'); } - $this->addElement('submit', 'submit', [ - 'label' => $label - ]); + $this->addElement('submit', 'submit', ['label' => $label]); } - public function onSuccess() + protected function onSuccess(): void { $this->migrations->applyPendingMigrations(); - Notification::success($this->translate( - 'Pending database schema migrations have successfully been applied' - )); + Notification::success($this->translate('Pending database schema migrations have successfully been applied')); } } diff --git a/library/Vspheredb/Web/Form/ChooseDbResourceForm.php b/library/Vspheredb/Web/Form/ChooseDbResourceForm.php index f041e736..76fd29a8 100644 --- a/library/Vspheredb/Web/Form/ChooseDbResourceForm.php +++ b/library/Vspheredb/Web/Form/ChooseDbResourceForm.php @@ -8,6 +8,7 @@ use gipfl\Web\Form; use gipfl\Web\Widget\Hint; use Icinga\Application\Config; +use Icinga\Data\Db\DbConnection; use Icinga\Data\ResourceFactory; use Icinga\Module\Vspheredb\Db; use Icinga\Web\Notification; @@ -18,22 +19,22 @@ class ChooseDbResourceForm extends Form { use Translation; - private $config; + private ?Config $config = null; - private $storeConfigLabel; + private ?string $storeConfigLabel = null; - private $createDbLabel; + private ?string $createDbLabel = null; - private $migrateDbLabel; + private ?string $migrateDbLabel = null; - protected function assemble() + protected function assemble(): void { $this->storeConfigLabel = $this->translate('Store configuration'); $this->addResourceConfigElements(); if ( - !$this->config()->get('db', 'resource') + ! $this->config()->get('db', 'resource') || ($this->config()->get('db', 'resource') !== $this->getResourceName()) ) { return; @@ -57,8 +58,7 @@ protected function assemble() $resource = $this->getResource(); $db = $resource->getDbAdapter(); } catch (Exception $e) { - $this->getElement('resource') - ->addMessage('Resource failed: ' . $e->getMessage()); + $this->getElement('resource')->addMessage('Resource failed: ' . $e->getMessage()); return; } @@ -66,8 +66,7 @@ protected function assemble() try { $db->fetchOne('SELECT 1'); } catch (Exception $e) { - $this->getElement('resource') - ->addMessage('Could not connect to database: ' . $e->getMessage()); + $this->getElement('resource')->addMessage('Could not connect to database: ' . $e->getMessage()); $this->add(Hint::info($this->translate( 'Please make sure that your database exists and your user has' @@ -77,7 +76,7 @@ protected function assemble() } } - protected function addResourceConfigElements() + protected function addResourceConfigElements(): void { $config = $this->config(); $resources = $this->enumResources(); @@ -90,7 +89,7 @@ protected function addResourceConfigElements() 'value' => $config->get('db', 'resource') ]); - if (!$this->getResourceName()) { + if (! $this->getResourceName()) { $this->add(Hint::info($this->translate( 'No database resource has been configured yet. Please choose a' . ' resource to complete your config' @@ -117,7 +116,7 @@ protected function addResourceConfigElements() /** * @return bool */ - protected function storeResourceConfig() + protected function storeResourceConfig(): bool { $config = $this->config(); $value = $this->getValue('resource'); @@ -130,7 +129,7 @@ protected function storeResourceConfig() Notification::success($this->translate('Configuration has been stored')); return true; - } catch (Exception $e) { + } catch (Exception) { $this->getElement('resource')->addMessage( sprintf( $this->translate( @@ -156,7 +155,7 @@ protected function storeResourceConfig() } } - public function onSuccess() + protected function onSuccess(): void { if ($this->getSubmitLabel() === $this->storeConfigLabel) { if ($this->storeResourceConfig()) { @@ -166,40 +165,37 @@ public function onSuccess() } } - if ( - $this->getSubmitLabel() === $this->createDbLabel - || $this->getSubmitLabel() === $this->migrateDbLabel - ) { + if ($this->getSubmitLabel() === $this->createDbLabel || $this->getSubmitLabel() === $this->migrateDbLabel) { $this->migrations()->applyPendingMigrations(); } } - protected function getSubmitLabel() + protected function getSubmitLabel(): string { return $this->getSubmitButton()->getButtonLabel(); } - protected function getResourceName() + protected function getResourceName(): ?string { if ($this->hasBeenSent()) { $resource = $this->getValue('resource'); $resources = $this->enumResources(); if (in_array($resource, $resources)) { return $resource; - } else { - return null; } - } else { - return $this->config()->get('db', 'resource'); + + return null; } + + return $this->config()->get('db', 'resource'); } - public function getDb() + public function getDb(): Db { return Db::fromResourceName($this->getResourceName()); } - protected function getResource() + protected function getResource(): DbConnection { return ResourceFactory::create($this->getResourceName()); } @@ -207,28 +203,27 @@ protected function getResource() /** * @return Migrations */ - protected function migrations() + protected function migrations(): Migrations { return Db::migrationsForDb($this->getDb()); } - public function setModuleConfig(Config $config) + public function setModuleConfig(Config $config): static { $this->config = $config; return $this; } - protected function config() + protected function config(): Config { - if ($this->config === null) { - $this->config = Config::module('vspheredb'); - } - - return $this->config; + return $this->config ??= Config::module('vspheredb'); } - protected function enumResources() + /** + * @return array + */ + protected function enumResources(): array { // return []; $resources = []; diff --git a/library/Vspheredb/Web/Form/ChooseInfluxDatabaseForm.php b/library/Vspheredb/Web/Form/ChooseInfluxDatabaseForm.php index 17d6c623..36bbc80c 100644 --- a/library/Vspheredb/Web/Form/ChooseInfluxDatabaseForm.php +++ b/library/Vspheredb/Web/Form/ChooseInfluxDatabaseForm.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Form; +use Exception; use gipfl\Web\Form; use gipfl\Web\Form\Element\TextWithActionButton; use Icinga\Module\Vspheredb\Daemon\RemoteClient; @@ -19,20 +20,13 @@ class ChooseInfluxDatabaseForm extends Form { use Translation; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - /** @var array|null|false */ - protected $dbList; + protected array|null|false $dbList = null; - /** - * @var RemoteClient - */ - protected $client; - /** - * @var PerfDataConsumerHook - */ - protected $hook; + protected RemoteClient $client; + + protected PerfDataConsumerHook $hook; public function __construct(LoopInterface $loop, RemoteClient $client, PerfDataConsumerHook $hook) { @@ -41,22 +35,22 @@ public function __construct(LoopInterface $loop, RemoteClient $client, PerfDataC $this->hook = $hook; } - public function assemble() + protected function assemble(): void { $this->addDbSelection(); } - protected function prepareParams() + protected function prepareParams(): array { return [ 'baseUrl' => $this->hook->getSetting('base_url'), 'apiVersion' => $this->hook->getSetting('api_version'), 'username' => $this->hook->getSetting('username'), - 'password' => $this->hook->getSetting('password'), + 'password' => $this->hook->getSetting('password') ]; } - protected function getDbList() + protected function getDbList(): false|array|null { if ($this->dbList === null) { $this->refreshDbList(); @@ -65,39 +59,35 @@ protected function getDbList() return $this->dbList; } - protected function remoteRequest($request, $params = []) + protected function remoteRequest(string $request, ?array $params = []): mixed { return await(timeout($this->client->request($request, $params), 5, $this->loop)); } - protected function refreshDbList() + protected function refreshDbList(): void { try { - $this->dbList = \array_filter( + $this->dbList = array_filter( (array) $this->remoteRequest('influxdb.listDatabases', $this->prepareParams()), - function ($value) { - return $value[0] !== '_'; - } + fn ($value) => $value[0] !== '_' ); - } catch (\Exception $e) { + } catch (Exception) { // Hint: we no longer refresh if it's false $this->dbList = false; } } - protected function createDatabase($name) + protected function createDatabase($name): mixed { Notification::info("Creating $name"); - $promise = $this->client->request('influxdb.createDatabase', $this->prepareParams() + [ - 'dbName' => $name - ]); + $promise = $this->client->request('influxdb.createDatabase', $this->prepareParams() + ['dbName' => $name]); $result = await($promise); Notification::info("DON $name"); return $result; } - protected function createRequestedDb(BaseFormElement $element, TextWithActionButton $action) + protected function createRequestedDb(BaseFormElement $element, TextWithActionButton $action): void { $name = $element->getValue(); try { @@ -109,7 +99,7 @@ protected function createRequestedDb(BaseFormElement $element, TextWithActionBut if ($element instanceof SelectElement) { $element->setOptions($dbOptions); } - if (\in_array($name, $dbOptions)) { + if (in_array($name, $dbOptions)) { $element->setValue($name); } else { $this->triggerElementError( @@ -118,19 +108,19 @@ protected function createRequestedDb(BaseFormElement $element, TextWithActionBut $name ); } - } catch (\Exception $e) { + } catch (Exception $e) { $element->addMessage($e->getMessage()); } } - protected function getDbOptions() + protected function getDbOptions(): array { return ['' => $this->translate('Please choose')] - + \array_combine($this->dbList, $this->dbList) + + array_combine($this->dbList, $this->dbList) + ['_new' => ' -> ' . $this->translate('Create a new Database')]; } - protected function addDbSelection() + protected function addDbSelection(): static { if ($this->getSentValue('dbname') === '_new') { $elDbName = $this->createElement('hidden', 'dbname'); @@ -147,7 +137,7 @@ protected function addDbSelection() } else { $elDbName = $this->createElement('text', 'dbname', [ 'label' => $this->translate('Database'), - 'required' => true, + 'required' => true ]); $this->addElement($elDbName); } @@ -155,7 +145,7 @@ protected function addDbSelection() $action = new TextWithActionButton('new_dbname', [ 'label' => $this->translate('New Database'), 'description' => $this->translate('New InfluxDB database name'), - 'required' => true, + 'required' => true ], [ 'label' => $this->translate('Create'), 'title' => $this->translate('Create a new InfluxDB database') diff --git a/library/Vspheredb/Web/Form/DeleteVCenterForm.php b/library/Vspheredb/Web/Form/DeleteVCenterForm.php index b99f0b2a..9e1aec2d 100644 --- a/library/Vspheredb/Web/Form/DeleteVCenterForm.php +++ b/library/Vspheredb/Web/Form/DeleteVCenterForm.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Form; +use Exception; use gipfl\Web\Form; use gipfl\Web\Form\Feature\NextConfirmCancel; use gipfl\Web\Widget\Hint; @@ -11,7 +12,6 @@ use Icinga\Web\Notification; use ipl\Html\Html; use ipl\I18n\Translation; -use Ramsey\Uuid\Uuid; use React\EventLoop\LoopInterface; use function React\Async\await; @@ -22,18 +22,13 @@ class DeleteVCenterForm extends Form protected $defaultDecoratorClass = null; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; - /** @var RemoteClient */ - protected $client; + protected RemoteClient $client; - /** @var LoopInterface */ - protected $loop; - /** - * @var Db - */ - protected $db; + protected LoopInterface $loop; + + protected Db $db; public function __construct(Db $db, VCenter $vCenter, RemoteClient $client, LoopInterface $loop) { @@ -43,7 +38,7 @@ public function __construct(Db $db, VCenter $vCenter, RemoteClient $client, Loop $this->loop = $loop; } - public function assemble() + protected function assemble(): void { $this->add(Html::tag('h3', $this->translate('Delete this vCenter'))); $this->add(Hint::warning($this->translate( @@ -62,19 +57,19 @@ public function assemble() ))->addToForm($this); } - public function onSuccess() + protected function onSuccess(): void { $db = $this->db->getDbAdapter(); // Delete the connection first. $db->delete('vcenter_server', $db->quoteInto('vcenter_id = ?', (int) $this->vCenter->get('id'))); try { - if (await($this->client->request('db.deleteVcenter', [$this->vCenter->get('id')]))) { - Notification::success($this->translate('vCenter data cleanup has been launched')); - } else { - Notification::success($this->translate('Failed to trigger vCenter data cleanup')); - } - } catch (\Exception $e) { + Notification::success( + await($this->client->request('db.deleteVcenter', [$this->vCenter->get('id')])) + ? $this->translate('vCenter data cleanup has been launched') + : $this->translate('Failed to trigger vCenter data cleanup') + ); + } catch (Exception $e) { Notification::error($e->getMessage()); } } diff --git a/library/Vspheredb/Web/Form/DisableServerForm.php b/library/Vspheredb/Web/Form/DisableServerForm.php index 8c32ff3e..f0cc4091 100644 --- a/library/Vspheredb/Web/Form/DisableServerForm.php +++ b/library/Vspheredb/Web/Form/DisableServerForm.php @@ -2,43 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Form; -use gipfl\Web\Form\Feature\NextConfirmCancel; -use gipfl\Web\InlineForm; -use ipl\I18n\Translation; - -class DisableServerForm extends InlineForm +class DisableServerForm extends ServerActionForm { - use Translation; - - protected $serverId; - - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; - - public function __construct($serverId, $db) - { - $this->serverId = $serverId; - $this->db = $db; - } - - public function getUniqueFormName() - { - return parent::getUniqueFormName() . '-' . $this->serverId; - } - - protected function assemble() - { - (new NextConfirmCancel( - NextConfirmCancel::buttonNext($this->translate('Disable')), - NextConfirmCancel::buttonConfirm($this->translate('Really disable')), - NextConfirmCancel::buttonCancel($this->translate('Cancel')) - ))->addToForm($this); - } - - public function onSuccess() - { - $this->db->update('vcenter_server', [ - 'enabled' => 'n' - ], $this->db->quoteInto('id = ?', $this->serverId)); - } + protected ?string $serverAction = 'disable'; } diff --git a/library/Vspheredb/Web/Form/Element/VCenterSelection.php b/library/Vspheredb/Web/Form/Element/VCenterSelection.php index 50e73fd7..b580e9ff 100644 --- a/library/Vspheredb/Web/Form/Element/VCenterSelection.php +++ b/library/Vspheredb/Web/Form/Element/VCenterSelection.php @@ -5,6 +5,7 @@ use Icinga\Authentication\Auth; use Icinga\Module\Vspheredb\Auth\RestrictionHelper; use Icinga\Module\Vspheredb\Db; +use ipl\Html\Attributes; use ipl\Html\FormElement\SelectElement; use ipl\I18n\Translation; use Ramsey\Uuid\Uuid; @@ -13,13 +14,11 @@ class VCenterSelection extends SelectElement { use Translation; - /** @var Db */ - protected $connection; + protected Db $connection; - /** @var Auth */ - protected $auth; + protected Auth $auth; - protected $optional = false; + protected bool $optional = false; public function __construct(Db $connection, Auth $auth, $required = false, $name = 'vcenter', $attributes = null) { @@ -27,19 +26,19 @@ public function __construct(Db $connection, Auth $auth, $required = false, $name $this->auth = $auth; parent::__construct($name, $attributes); $enum = $this->enumVCenters(); - $this->addAttributes([ - 'options' => $required ? $enum : ['' => $this->translate('All vCenters'),] + $enum, - 'class' => 'autosubmit', - ]); + $this->addAttributes(Attributes::create([ + 'options' => $required ? $enum : ['' => $this->translate('All vCenters')] + $enum, + 'class' => 'autosubmit' + ])); } - protected function enumVCenters() + protected function enumVCenters(): array { $db = $this->connection->getDbAdapter(); $pairs = $db->fetchPairs( $db->select()->from(['vc' => 'vcenter'], [ 'uuid' => 'LOWER(HEX(vc.instance_uuid))', - 'name' => "vc.name || ' (' || REPLACE(vc.api_name, 'VMware ', '') || ')'", + 'name' => "vc.name || ' (' || REPLACE(vc.api_name, 'VMware ', '') || ')'" ])->order('vc.name') ); $enum = []; diff --git a/library/Vspheredb/Web/Form/EnableServerForm.php b/library/Vspheredb/Web/Form/EnableServerForm.php index 39b8e28e..a789134b 100644 --- a/library/Vspheredb/Web/Form/EnableServerForm.php +++ b/library/Vspheredb/Web/Form/EnableServerForm.php @@ -2,43 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Form; -use gipfl\Web\Form\Feature\NextConfirmCancel; -use gipfl\Web\InlineForm; -use ipl\I18n\Translation; - -class EnableServerForm extends InlineForm +class EnableServerForm extends ServerActionForm { - use Translation; - - protected $serverId; - - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; - - public function __construct($serverId, $db) - { - $this->serverId = $serverId; - $this->db = $db; - } - - public function getUniqueFormName() - { - return parent::getUniqueFormName() . '-' . $this->serverId; - } - - protected function assemble() - { - (new NextConfirmCancel( - NextConfirmCancel::buttonNext($this->translate('Enable')), - NextConfirmCancel::buttonConfirm($this->translate('Really enable')), - NextConfirmCancel::buttonCancel($this->translate('Cancel')) - ))->addToForm($this); - } - - public function onSuccess() - { - $this->db->update('vcenter_server', [ - 'enabled' => 'y' - ], $this->db->quoteInto('id = ?', $this->serverId)); - } + protected ?string $serverAction = 'enable'; } diff --git a/library/Vspheredb/Web/Form/FilterHostParentForm.php b/library/Vspheredb/Web/Form/FilterHostParentForm.php index 5da1edd7..62917075 100644 --- a/library/Vspheredb/Web/Form/FilterHostParentForm.php +++ b/library/Vspheredb/Web/Form/FilterHostParentForm.php @@ -6,28 +6,31 @@ use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Util; use ipl\I18n\Translation; +use Zend_Db_Adapter_Abstract; class FilterHostParentForm extends Form { use Translation; + protected $method = 'GET'; + protected $useFormName = false; + protected $useCsrf = false; - protected $db; + protected Zend_Db_Adapter_Abstract $db; public function __construct(Db $connection) { $this->db = $connection->getDbAdapter(); - $this->setMethod('GET'); } - public function hasDefaultElementDecorator() + public function hasDefaultElementDecorator(): false { return false; } - protected function assemble() + protected function assemble(): void { $vMotionEvents = [ // 'MigrationEvent', @@ -35,7 +38,7 @@ protected function assemble() 'VmBeingHotMigratedEvent', 'VmEmigratingEvent', 'VmMigratedEvent', - 'VmFailedMigrateEvent', + 'VmFailedMigrateEvent' ]; $otherKnownEvents = [ @@ -56,11 +59,10 @@ protected function assemble() ]; $this->addElement('select', 'type', [ - 'options' => [ - '' => $this->translate('- filter by event type -') - ] + array_combine($vMotionEvents, $vMotionEvents) + 'options' => ['' => $this->translate('- filter by event type -')] + + array_combine($vMotionEvents, $vMotionEvents) + array_combine($otherKnownEvents, $otherKnownEvents), - 'class' => 'autosubmit', + 'class' => 'autosubmit' ]); $parents = $this->enumHostParents(); if (empty($parents)) { @@ -70,46 +72,38 @@ protected function assemble() } else { $this->addElement('select', 'parent', [ 'options' => ['' => $this->translate('- filter by parent -')] + $parents, - 'class' => 'autosubmit', + 'class' => 'autosubmit' ]); } } - public function onSuccess() + protected function onSuccess(): void { // Overriding ipl method, would otherwise render a "success" paragraph } public function getColors(): array { - $colors = [ - 'VmPoweredOffEvent' => [255, 0, 0], - 'VmResettingEvent' => [164, 0, 0], - 'VmBeingHotMigratedEvent' => [255, 164, 0], - 'VmReconfiguredEvent' => [164, 0, 128], - 'VmPoweredOnEvent' => [0, 164, 0], - 'VmCreatedEvent' => [0, 164, 0], - 'VmStartingEvent' => [119, 170, 255], - 'VmBeingCreatedEvent' => [119, 170, 255], - ]; - - $type = $this->getElement('type')->getValue() ?? ''; - - return $colors[$type] ?? $colors['VmReconfiguredEvent']; + return match ($this->getElement('type')->getValue()) { + 'VmPoweredOffEvent' => [255, 0, 0], + 'VmResettingEvent' => [164, 0, 0], + 'VmBeingHotMigratedEvent' => [255, 164, 0], + 'VmPoweredOnEvent', 'VmCreatedEvent' => [0, 164, 0], + 'VmStartingEvent', 'VmBeingCreatedEvent' => [119, 170, 255], + default => [164, 0, 128], // Use VmReconfiguredEvent as fallback + }; } - protected function enumHostParents() + protected function enumHostParents(): array { $db = $this->db; - $query = $db->select()->from( - ['p' => 'object'], - ['p.uuid', 'p.object_name'] - )->join( + $query = $db->select()->from(['p' => 'object'], ['p.uuid', 'p.object_name'])->join( ['c' => 'object'], - 'c.parent_uuid = p.uuid AND ' - . $db->quoteInto('c.object_type = ?', 'HostSystem') - . ' AND ' - . $db->quoteInto('p.object_type = ?', 'ClusterComputeResource'), + sprintf( + 'c.parent_uuid = p.uuid AND %s AND %s', + $db->quoteInto('c.object_type = ?', 'HostSystem'), + $db->quoteInto('p.object_type = ?', 'ClusterComputeResource') + ), [] )->group('p.uuid')->order('p.object_name'); diff --git a/library/Vspheredb/Web/Form/FilterVCenterForm.php b/library/Vspheredb/Web/Form/FilterVCenterForm.php index 8513057e..fabcf98a 100644 --- a/library/Vspheredb/Web/Form/FilterVCenterForm.php +++ b/library/Vspheredb/Web/Form/FilterVCenterForm.php @@ -7,45 +7,48 @@ use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Web\Form\Element\VCenterSelection; use ipl\I18n\Translation; +use Zend_Db_Adapter_Abstract; class FilterVCenterForm extends Form { use Translation; - /** @var Auth */ - protected $auth; + protected $method = 'GET'; - /** @var Db */ - protected $connection; + protected Auth $auth; - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected Db $connection; + + protected Zend_Db_Adapter_Abstract $db; protected $useFormName = false; + protected $defaultDecoratorClass = null; + protected $useCsrf = false; - protected $allowAllVCenters = false; + + protected bool $allowAllVCenters = false; public function __construct(Db $connection, Auth $auth) { $this->db = $connection->getDbAdapter(); - $this->setMethod('GET'); $this->auth = $auth; $this->connection = $connection; } - public function allowAllVCenters($allow = true): self + public function allowAllVCenters(bool $allow = true): static { $this->allowAllVCenters = $allow; + return $this; } - public function getHexUuid() + public function getHexUuid(): string { return $this->getElement('vcenter')->getValue(); } - protected function assemble() + protected function assemble(): void { $this->addElement(new VCenterSelection($this->connection, $this->auth, !$this->allowAllVCenters)); } diff --git a/library/Vspheredb/Web/Form/FormElementStealer.php b/library/Vspheredb/Web/Form/FormElementStealer.php index 7a4d14e9..cf2d7336 100644 --- a/library/Vspheredb/Web/Form/FormElementStealer.php +++ b/library/Vspheredb/Web/Form/FormElementStealer.php @@ -9,14 +9,12 @@ trait FormElementStealer { - protected $mainProperties = []; + protected array $mainProperties = []; - public function getValues() + public function getValues(): array { $values = parent::getValues(); - $mainProperties = array_merge($this->mainProperties, [ - 'settings', - ]); + $mainProperties = array_merge($this->mainProperties, ['settings']); $finalValues = []; $settings = []; foreach ($values as $key => $value) { @@ -31,7 +29,7 @@ public function getValues() return $finalValues; } - protected function addButtons($final, $selectProperty) + protected function addButtons(bool $final, string $selectProperty): void { if ($final) { $submit = new SubmitElement('submit', [ @@ -45,7 +43,7 @@ protected function addButtons($final, $selectProperty) if ($this->isNew()) { $back = new SubmitElement('btn_back', [ 'label' => $this->translate('Back'), - 'formnovalidate' => true, + 'formnovalidate' => true ]); $deco->dd()->add($back); $this->registerElement($back); @@ -53,9 +51,7 @@ protected function addButtons($final, $selectProperty) $this->setElementValue($selectProperty, null); } } else { - $delete = new SubmitElement('btn_delete', [ - 'label' => $this->translate('Delete') - ]); + $delete = new SubmitElement('btn_delete', ['label' => $this->translate('Delete')]); $deco->dd()->add($delete); $this->registerElement($delete); if ($delete->hasBeenPressed()) { @@ -64,13 +60,11 @@ protected function addButtons($final, $selectProperty) } } } else { - $this->addElement('submit', 'next', [ - 'label' => $this->translate('Next') - ]); + $this->addElement('submit', 'next', ['label' => $this->translate('Next')]); } } - protected function addFormElementsFrom(Form $form) + protected function addFormElementsFrom(Form $form): void { foreach ($this->getElements() as $mainElement) { if (! $mainElement->isIgnored()) { diff --git a/library/Vspheredb/Web/Form/InfluxDbConnectionForm.php b/library/Vspheredb/Web/Form/InfluxDbConnectionForm.php index b002f61c..e8fe8e57 100644 --- a/library/Vspheredb/Web/Form/InfluxDbConnectionForm.php +++ b/library/Vspheredb/Web/Form/InfluxDbConnectionForm.php @@ -2,9 +2,11 @@ namespace Icinga\Module\Vspheredb\Web\Form; +use Exception; use gipfl\Web\Form; use gipfl\Web\Form\Element\TextWithActionButton; use Icinga\Module\Vspheredb\Daemon\RemoteClient; +use ipl\Html\Attributes; use ipl\Html\FormElement\SelectElement; use ipl\I18n\Translation; use React\EventLoop\LoopInterface; @@ -18,20 +20,17 @@ class InfluxDbConnectionForm extends Form public const INFLUXDB_MIN_SUPPORTED_VERSION = '1.6.0'; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - protected $detectedApiVersion; + protected ?string $detectedApiVersion = null; - protected $influxDbVersion; + protected ?string $influxDbVersion = null; - protected $baseUrlElement; - /** - * @var RemoteClient - */ - protected $client; + protected ?TextWithActionButton $baseUrlElement = null; + + protected RemoteClient $client; - protected $checkedNow = false; + protected bool $checkedNow = false; public function __construct(LoopInterface $loop, RemoteClient $client) { @@ -39,14 +38,14 @@ public function __construct(LoopInterface $loop, RemoteClient $client) $this->client = $client; } - public function assemble() + protected function assemble(): void { $this->addHidden('checked_url', ['ignore' => true]); $this->addHidden('checked_api_version', ['ignore' => true]); $this->baseUrlElement = new TextWithActionButton('base_url', [ 'label' => $this->translate('Base URL'), 'description' => $this->translate('InfluxDB base URL, like http://influxdb.example.com:8086'), - 'required' => true, + 'required' => true ], [ 'label' => $this->translate('Verify'), 'title' => $this->translate('Attempt to establish a connection to your InfluxDB instance') @@ -55,20 +54,18 @@ public function assemble() $this->addElement('select', 'api_version', [ 'label' => $this->translate('API Version'), 'class' => 'autosubmit', - 'description' => $this->translate( - 'InfluxDB API version, autodetect should work fine' - ), + 'description' => $this->translate('InfluxDB API version, autodetect should work fine'), 'options' => [ '' => $this->translate('Autodetect'), 'v1' => 'v1', - 'v2' => 'v2', - ], + 'v2' => 'v2' + ] ]); $this->appendVersionInformation($this->getDetectedApiVersion(), $this->getInfluxDbVersion()); $this->addCredentials(); } - protected function addCredentials() + protected function addCredentials(): static { if ($this->getApiVersion() === 'v2') { $this->addV2Credentials(); @@ -80,9 +77,9 @@ protected function addCredentials() return $this; } - protected function validateCredentials() + protected function validateCredentials(): void { - if (!$this->checkedNow) { + if (! $this->checkedNow) { return; } $username = $this->getValue('username'); @@ -100,38 +97,32 @@ protected function validateCredentials() ) { $this->getElement('password')->getAttributes()->add('class', 'validated'); } - } catch (\Exception $e) { + } catch (Exception $e) { $this->getElement('password')->addMessage($this->getExceptionMessageWithoutPhpFile($e)); } } - protected function getExceptionMessageWithoutPhpFile(\Exception $e) + protected function getExceptionMessageWithoutPhpFile(Exception $e): string { return preg_replace('/\sin\s.+?\.php\(\d+\)/', '', $e->getMessage()); } - protected function remoteRequest($request, $params = []) + protected function remoteRequest(string $request, array $params = []): mixed { return await(timeout($this->client->request($request, $params), 5, $this->loop)); } - protected function getDetectedApiVersion() + protected function getDetectedApiVersion(): ?string { - if ($this->detectedApiVersion === null) { - $this->detectedApiVersion = $this->getApiVersionForVersionString( - $this->getInfluxDbVersion() - ); - } - - return $this->detectedApiVersion; + return $this->detectedApiVersion ??= $this->getApiVersionForVersionString($this->getInfluxDbVersion()); } - protected function getApiVersion() + protected function getApiVersion(): string { return $this->getValue('api_version', $this->getDetectedApiVersion()); } - protected function getInfluxDbVersion() + protected function getInfluxDbVersion(): ?string { if ($this->influxDbVersion === null) { $element = $this->getUrlElement(); @@ -147,31 +138,28 @@ protected function getInfluxDbVersion() } /** - * @return TextWithActionButton + * @return ?TextWithActionButton */ - protected function getUrlElement() + protected function getUrlElement(): ?TextWithActionButton { return $this->baseUrlElement; } - protected function markUrlAsValidated() + protected function markUrlAsValidated(): static { - $this - ->getUrlElement() - ->getElement() - ->addAttributes(['class' => 'validated']); + $this->getUrlElement()->getElement()->addAttributes(Attributes::create(['class' => 'validated'])); return $this; } - protected function autodetectIsUpToDate() + protected function autodetectIsUpToDate(): bool { $baseUrl = $this->getValue('base_url'); return $baseUrl && $this->getValue('checked_url') === $baseUrl; } - protected function appendVersionInformation($apiVersion, $detectedVersion) + protected function appendVersionInformation(?string $apiVersion, ?string $detectedVersion): void { if (empty($apiVersion) || empty($detectedVersion)) { return; @@ -179,95 +167,87 @@ protected function appendVersionInformation($apiVersion, $detectedVersion) $element = $this->getElement('api_version'); assert($element instanceof SelectElement); $autoOption = $element->getOption(''); - $autoOption->setLabel(\sprintf( - $this->translate('Autodetect: %s API, Version is %s'), - $apiVersion, - $detectedVersion - )); + $autoOption->setLabel( + sprintf($this->translate('Autodetect: %s API, Version is %s'), $apiVersion, $detectedVersion) + ); $selectedOption = $element->getOption($apiVersion); - $selectedOption->setLabel(\sprintf( - $this->translate('%s (detected %s)'), - $apiVersion, - $detectedVersion - )); + $selectedOption->setLabel(sprintf($this->translate('%s (detected %s)'), $apiVersion, $detectedVersion)); // $element->setValue($apiVersion); } - protected function addV1Credentials() + protected function addV1Credentials(): void { - $this->addElement('text', 'username', [ - 'label' => $this->translate('Username'), - ]); + $this->addElement('text', 'username', ['label' => $this->translate('Username')]); $this->addElement('password', 'password', [ - 'label' => $this->translate('Password'), - 'required' => $this->hasElementValue('username'), + 'label' => $this->translate('Password'), + 'required' => $this->hasElementValue('username') ]); } - protected function addV2Credentials() + protected function addV2Credentials(): void { $this->addElement('text', 'username', [ - 'label' => $this->translate('Organisation'), - 'required' => true, + 'label' => $this->translate('Organisation'), + 'required' => true ]); $this->addElement('text', 'password', [ - 'label' => $this->translate('Token'), + 'label' => $this->translate('Token'), // 'description' => $this->translate('InfluxDB Token (InfluxDB -> Data -> Tokens'), - 'required' => true, + 'required' => true ]); } - protected function detectInfluxDbVersion($baseUrl) + protected function detectInfluxDbVersion($baseUrl): false|string|null { if ($this->getValue('base_url') === null) { return null; } try { - $version = $this->remoteRequest('influxdb.discoverVersion', [ - 'baseUrl' => $baseUrl, - ]); + $version = $this->remoteRequest('influxdb.discoverVersion', ['baseUrl' => $baseUrl]); $version = ltrim($version, 'v'); if ($this->versionIsFine($version)) { $this->checkedNow = true; $this->setCheckedApiVersionFor($baseUrl, $version); $this->markUrlAsValidated(); + return $version; - } else { - throw new \Exception("Version $version is not supported"); } - } catch (\Exception $e) { + + throw new Exception("Version $version is not supported"); + } catch (Exception $e) { $this->triggerElementError('base_url', $e->getMessage()); + return false; } } - protected function tryCredentials($baseUrl, $apiVersion, $username, $password) + protected function tryCredentials(string $baseUrl, string $apiVersion, string $username, string $password): mixed { return $this->remoteRequest('influxdb.testConnection', [ - 'baseUrl' => $baseUrl, + 'baseUrl' => $baseUrl, 'apiVersion' => $apiVersion, - 'username' => $username, - 'password' => $password, + 'username' => $username, + 'password' => $password ]); } - protected function setCheckedApiVersionFor($baseUrl, $version) + protected function setCheckedApiVersionFor(string $baseUrl, string $version): void { $this->getElement('checked_url')->setValue($baseUrl); $this->setElementValue('checked_api_version', $version); } - protected function versionIsFine($version) + protected function versionIsFine(string $version): bool { - return \version_compare($version, static::INFLUXDB_MIN_SUPPORTED_VERSION, 'ge'); + return version_compare($version, static::INFLUXDB_MIN_SUPPORTED_VERSION, 'ge'); } - protected function getApiVersionForVersionString($version) + protected function getApiVersionForVersionString(?string $version): ?string { if ($version === null) { return null; } - return \version_compare($version, '1.999.999', 'gt') ? 'v2' : 'v1'; + return version_compare($version, '1.999.999', 'gt') ? 'v2' : 'v1'; } } diff --git a/library/Vspheredb/Web/Form/LogLevelForm.php b/library/Vspheredb/Web/Form/LogLevelForm.php index 2c77ad21..dfcf489b 100644 --- a/library/Vspheredb/Web/Form/LogLevelForm.php +++ b/library/Vspheredb/Web/Form/LogLevelForm.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Form; +use Exception; use gipfl\Web\Form\Feature\NextConfirmCancel; use gipfl\Web\InlineForm; use Icinga\Module\Vspheredb\Daemon\RemoteClient; @@ -16,14 +17,11 @@ class LogLevelForm extends InlineForm { use Translation; - /** @var RemoteClient */ - protected $client; + protected RemoteClient $client; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; - /** @var boolean */ - protected $talkedToSocket; + protected ?bool $talkedToSocket = null; public function __construct(RemoteClient $client, LoopInterface $loop) { @@ -31,18 +29,19 @@ public function __construct(RemoteClient $client, LoopInterface $loop) $this->loop = $loop; } - public function talkedToSocket() + public function talkedToSocket(): ?bool { return $this->talkedToSocket; } - protected function assemble() + protected function assemble(): void { try { $currentLevel = await($this->client->request('logger.getLogLevel')); $this->talkedToSocket = true; - } catch (\Exception $e) { + } catch (Exception) { $this->talkedToSocket = false; + return; } @@ -56,17 +55,17 @@ protected function assemble() $toggle->showWithConfirm(new SelectElement('log_level', [ 'options' => ['' => $this->translate('- please choose -')] + $this->listLogLevels(), 'required' => true, - 'value' => $currentLevel, + 'value' => $currentLevel ])); $toggle->addToForm($this); } - protected function onSuccess() + protected function onSuccess(): void { await($this->client->request('logger.setLogLevel', ['level' => $this->getValue('log_level')])); } - protected function listLogLevels() + protected function listLogLevels(): array { $levels = [ LogLevel::EMERGENCY, @@ -76,7 +75,7 @@ protected function listLogLevels() LogLevel::WARNING, LogLevel::NOTICE, LogLevel::INFO, - LogLevel::DEBUG, + LogLevel::DEBUG ]; return array_combine($levels, $levels); diff --git a/library/Vspheredb/Web/Form/MonitoringConnectionForm.php b/library/Vspheredb/Web/Form/MonitoringConnectionForm.php index 65c65211..2964b34e 100644 --- a/library/Vspheredb/Web/Form/MonitoringConnectionForm.php +++ b/library/Vspheredb/Web/Form/MonitoringConnectionForm.php @@ -2,6 +2,8 @@ namespace Icinga\Module\Vspheredb\Web\Form; +use Exception; +use gipfl\Web\Form; use gipfl\Web\Form\Decorator\DdDtDecorator; use gipfl\Web\Widget\Hint; use Icinga\Application\Config; @@ -11,18 +13,20 @@ use Icinga\Module\Vspheredb\Web\QueryParams; use Icinga\Web\Notification; use InvalidArgumentException; -use ipl\I18n\Translation; -use gipfl\Web\Form; use ipl\Html\FormElement\SubmitElement; use ipl\Html\Html; +use ipl\I18n\Translation; use Ramsey\Uuid\Uuid; +use Zend_Db_Adapter_Abstract; class MonitoringConnectionForm extends Form { use Translation; - protected $db; + protected Zend_Db_Adapter_Abstract $db; + protected bool $hasBeenDeleted = false; + protected ?int $id = null; public function __construct(Db $connection) @@ -36,7 +40,7 @@ public function hasBeenDeleted(): bool return $this->hasBeenDeleted; } - protected function assemble() + protected function assemble(): void { $this->add(Hint::info($this->translate( 'The vSphereDB module can hook into the Icinga monitoring module.' @@ -47,7 +51,7 @@ protected function assemble() $this->addElement('select', 'vcenter', [ 'label' => $this->translate('vCenter'), 'options' => $this->optionalEnum($this->enumVCenters()), - 'ignore' => true, + 'ignore' => true ]); $this->addElement('select', 'source_type', [ @@ -57,7 +61,7 @@ protected function assemble() // 'icinga2-api' => $this->translate('Icinga 2 API'), 'icingadb' => $this->translate('Icinga DB') ]), - 'class' => 'autosubmit', + 'class' => 'autosubmit' ]); $sourceType = $this->getElement('source_type')->getValue(); if (! $sourceType) { @@ -82,6 +86,7 @@ protected function assemble() $this->addElement('submit', 'submit', [ 'label' => $this->translate('Next') ]); + return; } @@ -94,8 +99,9 @@ protected function assemble() } else { throw new InvalidArgumentException("Resource '$resourceName' is not a DbConnection"); } - } catch (\Exception $e) { + } catch (Exception $e) { $this->getElement('source_resource_name')->addMessage($e->getMessage()); + return; } @@ -103,7 +109,7 @@ protected function assemble() 'name' => $this->translate('Hostname'), 'display_name' => $this->translate('Display Name'), 'address' => $this->translate('Address v4'), - 'address6' => $this->translate('Address v6'), + 'address6' => $this->translate('Address v6') ] + [$this->translate('Custom Variables') => $icingadbVars]); } else { try { @@ -113,85 +119,69 @@ protected function assemble() } else { throw new InvalidArgumentException("Resource '$resourceName' is not a DbConnection"); } - } catch (\Exception $e) { + } catch (Exception $e) { $this->getElement('source_resource_name')->addMessage($e->getMessage()); + return; } $varOptions = $this->optionalEnum([ 'host_name' => $this->translate('Hostname'), 'display_name' => $this->translate('Display Name'), - 'address' => $this->translate('Address'), + 'address' => $this->translate('Address') ] + [$this->translate('Custom Variables') => $idoVars]); } $this->add(Html::tag('h2', $this->translate('Host Systems'))); $this->add(Html::tag('p', $this->translate( - 'Map monitored hosts to physical Host Systems belonging to your' - . ' VMware environment' + 'Map monitored hosts to physical Host Systems belonging to your VMware environment' ))); $this->addElement('select', 'host_property', [ 'label' => $this->translate('Host System Property'), - 'description' => $this->translate( - 'Property of the Host System (known by the vSphereDB module)' - ), + 'description' => $this->translate('Property of the Host System (known by the vSphereDB module)'), 'options' => $this->optionalEnum([ 'host_name' => $this->translate('Hostname'), 'object_name' => $this->translate('Object Name'), 'sysinfo_uuid' => $this->translate('System (BIOS) UUID'), - 'service_tag' => $this->translate('IP Address'), - ]), + 'service_tag' => $this->translate('IP Address') + ]) ]); $this->addElement('select', 'monitoring_host_property', [ 'label' => $this->translate('Monitored Host Property'), - 'description' => $this->translate( - 'Property of the Host System (as known by Icinga)' - ), - 'options' => $varOptions, + 'description' => $this->translate('Property of the Host System (as known by Icinga)'), + 'options' => $varOptions ]); $this->add(Html::tag('h2', $this->translate('Virtual Machines'))); $this->add(Html::tag('p', $this->translate( - 'Map monitored hosts to Virtual Machines belonging to your' - . ' VMware environment' + 'Map monitored hosts to Virtual Machines belonging to your VMware environment' ))); $this->addElement('select', 'vm_property', [ 'label' => $this->translate('Virtual Machine Property'), - 'description' => $this->translate( - 'Property of the Virtual Machine (known by the vSphereDB module)' - ), + 'description' => $this->translate('Property of the Virtual Machine (known by the vSphereDB module)'), 'options' => $this->optionalEnum([ 'guest_host_name' => $this->translate('Guest Hostname'), 'object_name' => $this->translate('Object Name'), - 'bios_uuid' => $this->translate('BIOS UUID'), - ]), + 'bios_uuid' => $this->translate('BIOS UUID') + ]) ]); $this->addElement('select', 'monitoring_vm_host_property', [ 'label' => $this->translate('Monitored Host Property'), - 'description' => $this->translate( - 'Property of the Virtual Machine (as known by Icinga)' - ), - 'options' => $varOptions, + 'description' => $this->translate('Property of the Virtual Machine (as known by Icinga)'), + 'options' => $varOptions ]); - $submit = new SubmitElement('submit', [ - 'label' => $this->translate('Store') - ]); + $submit = new SubmitElement('submit', ['label' => $this->translate('Store')]); $this->addElement($submit); if ($id = $this->getId()) { - $delete = new SubmitElement('delete', [ - 'label' => $this->translate('Delete') - ]); + $delete = new SubmitElement('delete', ['label' => $this->translate('Delete')]); $deco = $submit->getWrapper(); assert($deco instanceof DdDtDecorator); $deco->dd()->add($delete); $this->registerElement($delete); if ($delete->hasBeenPressed()) { - $this->db->delete( - 'monitoring_connection', - $this->db->quoteInto('id = ?', $id) - ); + $this->db->delete('monitoring_connection', $this->db->quoteInto('id = ?', $id)); Notification::success($this->translate('Monitoring Integration has been deleted')); $this->hasBeenDeleted = true; } @@ -200,61 +190,39 @@ protected function assemble() public function getId(): ?int { - if ($this->id === null) { - if ($id = QueryParams::fromRequest($this->getRequest())->get('id')) { - $this->id = (int) $id; - } + if ($this->id === null && $id = QueryParams::fromRequest($this->getRequest())->get('id')) { + $this->id = (int) $id; } return $this->id; } - public function onSuccess() + protected function onSuccess(): void { $values = $this->getValues(); $db = $this->db; $id = $this->getId(); $vCenterUuid = $this->getValue('vcenter'); - if ($vCenterUuid === null) { - $values['vcenter_uuid'] = null; - } else { - $values['vcenter_uuid'] = Uuid::fromString($vCenterUuid)->getBytes(); - } + $values['vcenter_uuid'] = $vCenterUuid !== null ? Uuid::fromString($vCenterUuid)->getBytes() : null; if ($id) { - $db->update( - 'monitoring_connection', - $values, - $db->quoteInto('id = ?', $id) - ); + $db->update('monitoring_connection', $values, $db->quoteInto('id = ?', $id)); Notification::success($this->translate('Monitoring Integration has been modified')); } else { - $priority = (int) $db->fetchOne( - $db->select()->from('monitoring_connection', 'MAX(priority)') - ) + 1; - $db->insert('monitoring_connection', $values + [ - 'priority' => $priority, - ]); + $priority = (int) $db->fetchOne($db->select()->from('monitoring_connection', 'MAX(priority)')) + 1; + $db->insert('monitoring_connection', $values + ['priority' => $priority]); $this->id = (int) $db->lastInsertId(); Notification::success($this->translate('Monitoring Integration has been created')); } } - protected function enumIcingadbCustomVars(DbConnection $db) + protected function enumIcingadbCustomVars(DbConnection $db): array { $dba = $db->getDbAdapter(); $vars = $dba->fetchPairs( - $dba->select()->from( - ['cvs' => 'customvar'], - [ - 'varname' => 'cvs.name', - 'varcount' => 'COUNT(*)' - ] - )->join( - ['o' => 'host_customvar'], - 'o.customvar_id = cvs.id', - [] - ) + $dba->select() + ->from(['cvs' => 'customvar'], ['varname' => 'cvs.name', 'varcount' => 'COUNT(*)']) + ->join(['o' => 'host_customvar'], 'o.customvar_id = cvs.id', []) ->group('varname') ->order('varname') ); @@ -267,24 +235,16 @@ protected function enumIcingadbCustomVars(DbConnection $db) return $result; } - protected function enumIdoCustomVars(DbConnection $db) + protected function enumIdoCustomVars(DbConnection $db): array { $dba = $db->getDbAdapter(); $vars = $dba->fetchPairs( - $dba->select()->from( - ['cvs' => 'icinga_customvariablestatus'], - [ - 'varname' => 'cvs.varname', - 'varcount' => 'COUNT(*)' - ] - )->join( - ['o' => 'icinga_objects'], - 'o.object_id = cvs.object_id AND o.is_active = 1', - [] - ) - ->group('varname') - ->order('varname') + $dba->select() + ->from(['cvs' => 'icinga_customvariablestatus'], ['varname' => 'cvs.varname', 'varcount' => 'COUNT(*)']) + ->join(['o' => 'icinga_objects'], 'o.object_id = cvs.object_id AND o.is_active = 1', []) + ->group('varname') + ->order('varname') ); $result = []; @@ -297,22 +257,20 @@ protected function enumIdoCustomVars(DbConnection $db) /** * UNUSED + * * @return array */ protected function enumHostParents(): array { $db = $this->db; - $query = $db->select()->from( - ['p' => 'object'], - ['p.uuid', 'p.object_name'] - )->join( - ['c' => 'object'], - 'c.parent_uuid = p.uuid AND ' - . $db->quoteInto('c.object_type = ?', 'HostSystem') - . ' AND ' - . $db->quoteInto('p.object_type = ?', 'ClusterComputeResource'), - [] - )->group('p.uuid')->order('p.object_name'); + $query = $db->select() + ->from(['p' => 'object'], ['p.uuid', 'p.object_name']) + ->join(['c' => 'object'], sprintf( + 'c.parent_uuid = p.uuid AND %s AND %s', + $db->quoteInto('c.object_type = ?', 'HostSystem'), + $db->quoteInto('p.object_type = ?', 'ClusterComputeResource') + ), []) + ->group('p.uuid')->order('p.object_name'); return $this->makeNiceUuidKeys($db->fetchPairs($query)); } @@ -343,10 +301,9 @@ protected function enumIdoResourceNames(): array protected function enumVCenters(): array { return $this->makeNiceUuidKeys($this->db->fetchPairs( - $this->db->select()->from(['vc' => 'vcenter'], [ - 'uuid' => 'vc.instance_uuid', - 'name' => 'vc.name', - ])->order('vc.name') + $this->db->select() + ->from(['vc' => 'vcenter'], ['uuid' => 'vc.instance_uuid', 'name' => 'vc.name']) + ->order('vc.name') )); } diff --git a/library/Vspheredb/Web/Form/ObjectForm.php b/library/Vspheredb/Web/Form/ObjectForm.php index e2d58025..b1295e89 100644 --- a/library/Vspheredb/Web/Form/ObjectForm.php +++ b/library/Vspheredb/Web/Form/ObjectForm.php @@ -2,35 +2,33 @@ namespace Icinga\Module\Vspheredb\Web\Form; +use gipfl\Web\Form; +use gipfl\ZfDbStore\StorableInterface; use gipfl\ZfDbStore\Store; use Icinga\Authentication\Auth; +use ipl\I18n\Translation; use Ramsey\Uuid\Uuid; use RuntimeException; -use ipl\I18n\Translation; -use gipfl\Web\Form; -use gipfl\ZfDbStore\StorableInterface; abstract class ObjectForm extends Form { use Translation; - /** @var Store */ - protected $store; + protected Store $store; - /** @var StorableInterface */ - protected $object; + protected ?StorableInterface $object = null; - protected $class; + /** @var ?class-string */ + protected ?string $class = null; - protected $wasNew = true; + protected bool $wasNew = true; public function __construct(Store $store) { $this->store = $store; - $this->setMethod('POST'); } - public function setObject(StorableInterface $object) + public function setObject(StorableInterface $object): static { $this->object = $object; $this->populate($object->getProperties()); @@ -42,41 +40,38 @@ public function setObject(StorableInterface $object) /** * @return ?StorableInterface */ - public function getObject() + public function getObject(): ?StorableInterface { return $this->object; } - public function wasNew() + public function wasNew(): bool { return $this->wasNew; } - public function isNew() + public function isNew(): bool { - return $this->object === null || $this->object->isNew(); + return $this->object?->isNew() ?? true; } - protected function getObjectClass() + protected function getObjectClass(): string { if ($this->class === null) { - throw new RuntimeException(sprintf( - 'ObjectForm %s defined no $class', - get_class($this) - )); + throw new RuntimeException(sprintf('ObjectForm %s defined no $class', get_class($this))); } return $this->class; } - protected static function now() + protected static function now(): float { $time = explode(' ', microtime()); return round(1000 * ((int)$time[1] + (float)$time[0])); } - public function onSuccess() + protected function onSuccess(): void { if ($this->object) { $object = $this->object; @@ -94,7 +89,7 @@ public function onSuccess() $this->store->store($object); } - protected function createObject() + protected function createObject(): mixed { /** @var StorableInterface $class Not really an object, it's a class name */ $class = $this->getObjectClass(); diff --git a/library/Vspheredb/Web/Form/PerfdataConsumerForm.php b/library/Vspheredb/Web/Form/PerfdataConsumerForm.php index 06c18679..4ff9c141 100644 --- a/library/Vspheredb/Web/Form/PerfdataConsumerForm.php +++ b/library/Vspheredb/Web/Form/PerfdataConsumerForm.php @@ -2,13 +2,11 @@ namespace Icinga\Module\Vspheredb\Web\Form; -use ipl\I18n\Translation; -use gipfl\Web\Form\Decorator\DdDtDecorator; use gipfl\ZfDbStore\Store; use Icinga\Module\Vspheredb\Daemon\RemoteClient; use Icinga\Module\Vspheredb\Hook\PerfDataConsumerHook; use Icinga\Module\Vspheredb\Storable\PerfdataConsumer; -use ipl\Html\FormElement\SubmitElement; +use ipl\I18n\Translation; use React\EventLoop\LoopInterface; class PerfdataConsumerForm extends ObjectForm @@ -18,13 +16,11 @@ class PerfdataConsumerForm extends ObjectForm public const ON_DELETE = 'delete'; - protected $class = PerfdataConsumer::class; + protected ?string $class = PerfdataConsumer::class; - /** @var RemoteClient */ - protected $client; + protected RemoteClient $client; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; public function __construct(LoopInterface $loop, RemoteClient $client, Store $store) { @@ -33,17 +29,17 @@ public function __construct(LoopInterface $loop, RemoteClient $client, Store $st parent::__construct($store); } - public function assemble() + protected function assemble(): void { $this->addElement('text', 'name', [ 'label' => $this->translate('Name'), 'required' => true, - 'description' => $this->translate('Arbitrary unique name for this Performance Data Consumer'), + 'description' => $this->translate('Arbitrary unique name for this Performance Data Consumer') ]); $this->addElement('boolean', 'enabled', [ 'label' => $this->translate('Enabled'), 'value' => 'y', - 'required' => true, + 'required' => true ]); if ($this->object instanceof PerfdataConsumer && !$this->hasBeenSent()) { $this->populate((array) $this->object->settings()); @@ -56,7 +52,7 @@ public function assemble() $this->addButtons(isset($implementation), 'implementation'); } - public function isValidEvent($event) + public function isValidEvent($event): bool { if ($event === self::ON_DELETE) { return true; @@ -65,7 +61,7 @@ public function isValidEvent($event) return parent::isValidEvent($event); } - protected function selectImplementation() + protected function selectImplementation(): ?string { if (! $this->isNew()) { return $this->object->get('implementation'); @@ -74,13 +70,13 @@ protected function selectImplementation() 'label' => $this->translate('Implementation'), 'options' => ['' => $this->translate('- please choose -')] + PerfDataConsumerHook::enum(), 'required' => true, - 'class' => 'autosubmit', + 'class' => 'autosubmit' ]); return $this->getValue('implementation'); } - protected function addImplementation($implementation) + protected function addImplementation(string $implementation): void { /** @var PerfDataConsumerHook $instance */ $class = PerfDataConsumerHook::getClass($implementation); @@ -89,6 +85,7 @@ protected function addImplementation($implementation) $this->translate('There is no such PerfdataConsumer: %s'), $implementation )); + return; } $instance = new $class(); diff --git a/library/Vspheredb/Web/Form/RestartDaemonForm.php b/library/Vspheredb/Web/Form/RestartDaemonForm.php index 6215bb0c..1da1c496 100644 --- a/library/Vspheredb/Web/Form/RestartDaemonForm.php +++ b/library/Vspheredb/Web/Form/RestartDaemonForm.php @@ -14,11 +14,9 @@ class RestartDaemonForm extends InlineForm { use Translation; - /** @var RemoteClient */ - protected $client; + protected RemoteClient $client; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; public function __construct(RemoteClient $client, LoopInterface $loop) { @@ -26,18 +24,18 @@ public function __construct(RemoteClient $client, LoopInterface $loop) $this->loop = $loop; } - protected function assemble() + protected function assemble(): void { (new NextConfirmCancel( NextConfirmCancel::buttonNext($this->translate('Restart'), [ - 'title' => $this->translate('Click to restart the vSphereDB background daemon'), + 'title' => $this->translate('Click to restart the vSphereDB background daemon') ]), NextConfirmCancel::buttonConfirm($this->translate('Yes, please restart')), NextConfirmCancel::buttonCancel($this->translate('Cancel')) ))->addToForm($this); } - protected function onSuccess() + protected function onSuccess(): void { await($this->client->request('process.restart')); } diff --git a/library/Vspheredb/Web/Form/ServerActionForm.php b/library/Vspheredb/Web/Form/ServerActionForm.php new file mode 100644 index 00000000..4710a910 --- /dev/null +++ b/library/Vspheredb/Web/Form/ServerActionForm.php @@ -0,0 +1,51 @@ +serverId = $serverId; + $this->db = $db; + } + + public function getUniqueFormName(): string + { + return parent::getUniqueFormName() . '-' . $this->serverId; + } + + protected function assemble(): void + { + (new NextConfirmCancel( + NextConfirmCancel::buttonNext($this->translate(ucfirst($this->serverAction))), + NextConfirmCancel::buttonConfirm($this->translate('Really ' . $this->serverAction)), + NextConfirmCancel::buttonCancel($this->translate('Cancel')) + ))->addToForm($this); + } + + protected function onSuccess(): void + { + $enabled = match ($this->serverAction) { + 'enable' => 'y', + 'disable' => 'n', + default => throw new ProgrammingError('Invalid server action provided: %s', $this->serverAction) + }; + $this->db->update('vcenter_server', ['enabled' => $enabled], $this->db->quoteInto('id = ?', $this->serverId)); + } +} diff --git a/library/Vspheredb/Web/Form/VCenterForm.php b/library/Vspheredb/Web/Form/VCenterForm.php index 4a691a34..226399b8 100644 --- a/library/Vspheredb/Web/Form/VCenterForm.php +++ b/library/Vspheredb/Web/Form/VCenterForm.php @@ -11,8 +11,7 @@ class VCenterForm extends Form { use Translation; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VCenter $vCenter) { @@ -20,7 +19,7 @@ public function __construct(VCenter $vCenter) $this->populate($vCenter->getProperties()); } - public function assemble() + protected function assemble(): void { $this->add(Html::tag('h3', $this->translate('Rename this vCenter'))); $this->addElement('text', 'name', [ @@ -28,14 +27,14 @@ public function assemble() 'description' => $this->translate( 'You might want to change the display name of your vCenter.' . ' This defaults to the first related Server host name.' - ), + ) ]); $this->addElement('submit', 'submit', [ 'label' => $this->translate('Rename') ]); } - public function onSuccess() + protected function onSuccess(): void { $this->vCenter->setProperties($this->getValues())->store(); } diff --git a/library/Vspheredb/Web/Form/VCenterServerForm.php b/library/Vspheredb/Web/Form/VCenterServerForm.php index e3f88352..76f58e98 100644 --- a/library/Vspheredb/Web/Form/VCenterServerForm.php +++ b/library/Vspheredb/Web/Form/VCenterServerForm.php @@ -4,7 +4,6 @@ use gipfl\Web\Form; use Icinga\Module\Vspheredb\Db; -use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use Icinga\Module\Vspheredb\DbObject\VCenterServer; use ipl\Html\FormElement\SubmitElement; use ipl\I18n\Translation; @@ -15,26 +14,21 @@ class VCenterServerForm extends Form public const UNCHANGED_PASSWORD = '__UNCHANGED__'; - protected $objectClassName = VCenterServer::class; + protected ?VCenterServer $object = null; - /** @var VCenterServer */ - protected $object; + protected Db $db; - protected $db; - - protected $deleted = false; + protected bool $deleted = false; public function __construct(Db $db) { $this->db = $db; } - public function assemble() + protected function assemble(): void { if (! class_exists('SoapClient')) { - $this->addMessage($this->translate( - 'The PHP SOAP extension (php-soap) is not installed/enabled' - )); + $this->addMessage($this->translate('The PHP SOAP extension (php-soap) is not installed/enabled')); return; } @@ -49,31 +43,27 @@ public function assemble() . ' HTTP(s) ports' ), 'class' => 'autofocus', - 'required' => true, + 'required' => true ]); $this->addElement('select', 'scheme', [ 'label' => $this->translate('Protocol'), - 'description' => $this->translate( - 'Whether to use encryption when talking to your vCenter' - ), + 'description' => $this->translate('Whether to use encryption when talking to your vCenter'), 'multiOptions' => [ 'https' => $this->translate('HTTPS (strongly recommended)'), - 'http' => $this->translate('HTTP (this is plaintext!)'), + 'http' => $this->translate('HTTP (this is plaintext!)') ], 'class' => 'autosubmit', 'value' => 'https', - 'required' => true, + 'required' => true ]); $ssl = $this->getValue('scheme', 'https') === 'https'; $this->addElement('boolean', 'enabled', [ 'label' => $this->translate('Enabled'), - 'description' => $this->translate( - 'Whether the background daemon should actively poll this node.' - ), + 'description' => $this->translate('Whether the background daemon should actively poll this node.'), 'required' => true, - 'value' => 'y', + 'value' => 'y' ]); if ($ssl) { @@ -84,38 +74,31 @@ public function assemble() . ' been signed by a trusted CA. This is strongly recommended.' ), 'required' => true, - 'value' => 'y', + 'value' => 'y' ]); $this->addElement('boolean', 'ssl_verify_host', [ 'label' => $this->translate('Verify Host'), 'description' => $this->translate( - 'Whether we should check that the certificate matches the' - . 'configured host' + 'Whether we should check that the certificate matches the configured host' ), 'value' => 'y', - 'required' => true, + 'required' => true ]); } $this->addElement('text', 'username', [ 'label' => $this->translate('Username'), - 'description' => $this->translate( - 'Will be used for SOAP authentication against your vCenter' - ), - 'required' => true, + 'description' => $this->translate('Will be used for SOAP authentication against your vCenter'), + 'required' => true ]); - if ($this->isNew()) { - $this->addElement('password', 'password', [ - 'label' => $this->translate('Password'), - 'required' => true, - ]); - } else { - $this->addElement('password', 'password', [ - 'label' => $this->translate('Password'), - 'placeholder' => $this->translate('(keep as stored)'), - ]); - } + $this->addElement( + 'password', + 'password', + ['label' => $this->translate('Password')] + ($this->isNew() + ? ['required' => true] + : ['placeholder' => $this->translate('(keep as stored)')]) + ); $this->addElement('select', 'proxy_type', [ 'label' => $this->translate('Proxy'), @@ -126,7 +109,7 @@ public function assemble() 'multiOptions' => [ '' => $this->translate('- please choose -'), 'HTTP' => $this->translate('HTTP proxy'), - 'SOCKS5' => $this->translate('SOCKS5 proxy'), + 'SOCKS5' => $this->translate('SOCKS5 proxy') ], 'class' => 'autosubmit' ]); @@ -136,21 +119,18 @@ public function assemble() if ($proxyType) { $this->addElement('text', 'proxy_address', [ 'label' => $this->translate('Proxy Address'), - 'description' => $this->translate( - 'Hostname, IP or :' - ), - 'required' => true, + 'description' => $this->translate('Hostname, IP or :'), + 'required' => true ]); if ($proxyType === 'HTTP') { $this->addElement('text', 'proxy_user', [ 'label' => $this->translate('Proxy Username'), 'description' => $this->translate( - 'In case your proxy requires authentication, please' - . ' configure this here' - ), + 'In case your proxy requires authentication, please configure this here' + ) ]); - $passRequired = $this->getValue('proxy_user') !== null && \strlen($this->getValue('proxy_user')) > 0; + $passRequired = $this->getValue('proxy_user') !== null && strlen($this->getValue('proxy_user')) > 0; $this->addElement('password', 'proxy_pass', [ 'label' => $this->translate('Proxy Password'), @@ -164,9 +144,7 @@ public function assemble() 'label' => $this->isNew() ? $this->translate('Create') : $this->translate('Store') ]); if (! $this->isNew()) { - $buttons[] = $deleteButton = new SubmitElement('btn_delete', [ - 'label' => $this->translate('Delete') - ]); + $buttons[] = $deleteButton = new SubmitElement('btn_delete', ['label' => $this->translate('Delete')]); } else { $deleteButton = null; } @@ -180,12 +158,12 @@ public function assemble() } } - public function isNew() + public function isNew(): bool { return $this->object === null || ! $this->object->hasBeenLoadedFromDb(); } - public function getValues() + public function getValues(): array { $values = parent::getValues(); if (! $this->isNew()) { @@ -200,14 +178,14 @@ public function getValues() return $values; } - public function setObject(VCenterServer $object) + public function setObject(VCenterServer $object): static { $this->object = $object; $properties = $object->getProperties(); - if ($properties['password'] !== null && \strlen($properties['password'])) { + if ($properties['password'] !== null && strlen($properties['password'])) { $properties['password'] = self::UNCHANGED_PASSWORD; } - if ($properties['proxy_pass'] !== null && \strlen($properties['proxy_pass'])) { + if ($properties['proxy_pass'] !== null && strlen($properties['proxy_pass'])) { $properties['proxy_pass'] = self::UNCHANGED_PASSWORD; } $this->populate($properties); @@ -216,25 +194,19 @@ public function setObject(VCenterServer $object) } /** - * @return BaseDbObject + * @return VCenterServer */ - public function getObject() + public function getObject(): VCenterServer { - if ($this->object === null) { - /** @var BaseDbObject $class */ - $class = $this->objectClassName; - $this->object = $class::create([], $this->db); - } - - return $this->object; + return $this->object ??= VCenterServer::create([], $this->db); } - public function hasBeenDeleted() + public function hasBeenDeleted(): bool { return $this->deleted; } - public function onSuccess() + protected function onSuccess(): void { $this->getObject()->setProperties($this->getValues()); } diff --git a/library/Vspheredb/Web/Form/VCenterShipMetricsForm.php b/library/Vspheredb/Web/Form/VCenterShipMetricsForm.php index a4a7f8c7..78111fbf 100644 --- a/library/Vspheredb/Web/Form/VCenterShipMetricsForm.php +++ b/library/Vspheredb/Web/Form/VCenterShipMetricsForm.php @@ -21,19 +21,16 @@ class VCenterShipMetricsForm extends ObjectForm public const ON_DELETE = 'delete'; - protected $class = PerfdataSubscription::class; + protected ?string $class = PerfdataSubscription::class; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; - /** @var PerfdataConsumer[] */ - protected $consumers; + /** @var ?PerfdataConsumer[] */ + protected ?array $consumers = null; - /** @var RemoteClient */ - protected $remoteClient; + protected RemoteClient $remoteClient; - /** @var LoopInterface */ - protected $loop; + protected LoopInterface $loop; public function __construct(ZfDbStore $store, VCenter $vCenter, RemoteClient $client, LoopInterface $loop) { @@ -44,10 +41,13 @@ public function __construct(ZfDbStore $store, VCenter $vCenter, RemoteClient $cl $this->populate($vCenter->getProperties()); } - protected function fetchConsumers() + /** + * @return PerfdataConsumer[] + */ + protected function fetchConsumers(): array { $db = $this->vCenter->getConnection()->getDbAdapter(); - /** @var PerfdataConsumer $consumers */ + /** @var PerfdataConsumer[] $consumers */ $consumers = []; foreach ($db->fetchAll($db->select()->from('perfdata_consumer')) as $row) { $consumers[Uuid::fromBytes($row->uuid)->toString()] = PerfdataConsumer::create((array) $row); @@ -56,17 +56,12 @@ protected function fetchConsumers() return $consumers; } - protected function enumConsumers($consumers) + protected function enumConsumers($consumers): array { - $result = []; - foreach ($consumers as $uuid => $consumer) { - $result[$uuid] = $consumer->get('name'); - } - - return $result; + return array_map(fn ($consumer) => $consumer->get('name'), $consumers); } - public function assemble() + protected function assemble(): void { $this->add(Html::tag('h3', $this->translate('Ship Performance Data'))); if ($this->object instanceof PerfdataSubscription && !$this->hasBeenSent()) { @@ -80,16 +75,12 @@ public function assemble() } /** - * @return PerfdataConsumer|null + * @return ?PerfdataConsumer */ - protected function selectConsumer() + protected function selectConsumer(): ?PerfdataConsumer { $consumers = $this->fetchConsumers(); - if ($this->object) { - $consumer = Uuid::fromBytes($this->object->get('consumer_uuid'))->toString(); - } else { - $consumer = null; - } + $consumer = $this->object ? Uuid::fromBytes($this->object->get('consumer_uuid'))->toString() : null; $this->addElement('select', 'consumer', [ 'label' => $this->translate('Consumer'), 'options' => ['' => $this->translate('- please choose -')] + $this->enumConsumers($consumers), @@ -99,11 +90,9 @@ protected function selectConsumer() ), 'required' => true, 'value' => $consumer, - 'class' => 'autosubmit', - ]); - $this->addHidden('enabled', [ - 'value' => 'y' + 'class' => 'autosubmit' ]); + $this->addHidden('enabled', ['value' => 'y']); $value = $this->getValue('consumer') ?? ''; if (isset($consumers[$value])) { @@ -113,7 +102,7 @@ protected function selectConsumer() return null; } - protected function addConsumerConfig($consumer) + protected function addConsumerConfig($consumer): void { $instance = PerfDataConsumerHook::createConsumerInstance($consumer, $this->loop); if ($form = $instance->getSubscriptionForm($this->remoteClient)) { @@ -121,7 +110,7 @@ protected function addConsumerConfig($consumer) } } - public function isValidEvent($event) + public function isValidEvent($event): bool { if ($event === self::ON_DELETE) { return true; @@ -130,7 +119,7 @@ public function isValidEvent($event) return parent::isValidEvent($event); } - public function createObject() + public function createObject(): mixed { $object = parent::createObject(); $object->set('vcenter_uuid', $this->vCenter->get('instance_uuid')); diff --git a/library/Vspheredb/Web/OverviewTree.php b/library/Vspheredb/Web/OverviewTree.php index 628b3509..4c751e25 100644 --- a/library/Vspheredb/Web/OverviewTree.php +++ b/library/Vspheredb/Web/OverviewTree.php @@ -8,35 +8,34 @@ use Icinga\Module\Vspheredb\Util; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\I18n\Translation; class OverviewTree extends BaseHtmlElement { use Translation; - /** @var Db */ - protected $db; + protected Db $db; - /** @var RestrictionHelper */ - protected $restrictionHelper; + protected RestrictionHelper $restrictionHelper; protected $tag = 'ul'; protected $defaultAttributes = [ 'class' => 'tree', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - protected $typeFilter; + protected ?string $typeFilter; - public function __construct(Db $db, RestrictionHelper $restrictionHelper, $typeFilter = null) + public function __construct(Db $db, RestrictionHelper $restrictionHelper, ?string $typeFilter = null) { $this->db = $db; $this->typeFilter = $typeFilter; $this->restrictionHelper = $restrictionHelper; } - public function renderContent() + public function renderContent(): string { $this->add( $this->dumpTree( @@ -51,18 +50,11 @@ public function renderContent() return parent::renderContent(); } - protected function getTree() + protected function getTree(): array { $tree = []; $all = []; foreach ($this->fetchTree() as $item) { - if ( - $this->typeFilter - && (string) $item->parent_object_type === 'Datacenter' - && $item->object_name !== $this->typeFilter - ) { - // continue; // see #260 - } $item->children = []; /** @var string $uuid */ @@ -81,37 +73,30 @@ protected function getTree() return $tree; } - protected function fetchTree() + protected function fetchTree(): ?array { $db = $this->db->getDbAdapter(); - $hostCnt = $db->select()->from('object', [ - 'cnt' => 'COUNT(*)', - 'parent_uuid' => 'parent_uuid' - ])->where('object_type = ?', 'HostSystem')->group('parent_uuid'); - $vmCnt = $db->select()->from('object', [ - 'cnt' => 'COUNT(*)', - 'parent_uuid' => 'parent_uuid' - ])->where('object_type = ?', 'VirtualMachine')->group('parent_uuid'); - $dsCnt = $db->select()->from('object', [ - 'cnt' => 'COUNT(*)', - 'parent_uuid' => 'parent_uuid' - ])->where('object_type = ?', 'Datastore')->group('parent_uuid'); - $networkCnt = $db->select()->from('object', [ - 'cnt' => 'COUNT(*)', - 'parent_uuid' => 'parent_uuid' - ])->where('object_type = ?', 'DistributedVirtualSwitch')->group('parent_uuid'); + $hostCnt = $db->select() + ->from('object', ['cnt' => 'COUNT(*)', 'parent_uuid' => 'parent_uuid']) + ->where('object_type = ?', 'HostSystem') + ->group('parent_uuid'); + $vmCnt = $db->select() + ->from('object', ['cnt' => 'COUNT(*)', 'parent_uuid' => 'parent_uuid']) + ->where('object_type = ?', 'VirtualMachine') + ->group('parent_uuid'); + $dsCnt = $db->select() + ->from('object', ['cnt' => 'COUNT(*)', 'parent_uuid' => 'parent_uuid']) + ->where('object_type = ?', 'Datastore') + ->group('parent_uuid'); + $networkCnt = $db->select() + ->from('object', ['cnt' => 'COUNT(*)', 'parent_uuid' => 'parent_uuid']) + ->where('object_type = ?', 'DistributedVirtualSwitch') + ->group('parent_uuid'); $main = $db->select() - ->from(['o' => 'object'], [ - 'o.*', - 'parent_object_type' => 'po.object_type', - ]) + ->from(['o' => 'object'], ['o.*', 'parent_object_type' => 'po.object_type']) ->joinLeft(['po' => 'object'], 'po.uuid = o.parent_uuid', []) - ->where(' o.object_type NOT IN (?)', [ - 'VirtualMachine', - 'HostSystem', - 'Datastore' - ]); + ->where(' o.object_type NOT IN (?)', ['VirtualMachine', 'HostSystem', 'Datastore']); $this->restrictionHelper->filterQuery($hostCnt); $this->restrictionHelper->filterQuery($vmCnt); $this->restrictionHelper->filterQuery($dsCnt); @@ -123,7 +108,7 @@ protected function fetchTree() 'cnt_host' => 'hc.cnt', 'cnt_vm' => 'vc.cnt', 'cnt_ds' => 'dc.cnt', - 'cnt_network' => 'nc.cnt', + 'cnt_network' => 'nc.cnt' ]) ->joinLeft(['vc' => $vmCnt], 'vc.parent_uuid = f.uuid', []) ->joinLeft(['hc' => $hostCnt], 'hc.parent_uuid = f.uuid', []) @@ -135,54 +120,41 @@ protected function fetchTree() return $this->db->getDbAdapter()->fetchAll($query); } - protected function dumpTree($tree, $level = 0) + protected function dumpTree(object $tree, int $level = 0): HtmlElement { $hasChildren = ! empty($tree->children); $type = $tree->object_type; $li = Html::tag('li'); - if (! $hasChildren) { - $li->getAttributes()->add('class', 'collapsed'); - } if ($hasChildren) { $li->add(Html::tag('span', ['class' => 'handle'])); + } else { + $li->getAttributes()->add('class', 'collapsed'); } if ($level === 0) { - $li->add(Html::tag('a', [ - 'name' => $tree->object_name, - 'class' => 'icon-globe' - ], $tree->object_name)); + $li->add(Html::tag('a', ['name' => $tree->object_name, 'class' => 'icon-globe'], $tree->object_name)); } else { $count = $tree->cnt_vm + $tree->cnt_host + $tree->cnt_ds; - if ($count) { - $label = sprintf('%s (%d)', $tree->object_name, $count); - // $label = sprintf('%s (%d VMs, %d Hosts)', $tree->object_name, $tree->cnt_vm, $tree->cnt_host); - } else { - $label = $tree->object_name; - } - $attributes = [ - 'class' => [$this->getClassByType($type), $tree->overall_status] - ]; + $label = $count ? sprintf('%s (%d)', $tree->object_name, $count) : $tree->object_name; + $attributes = ['class' => [$this->getClassByType($type), $tree->overall_status]]; - if ($count) { - $li->add(Link::create( + $link = $count + ? Link::create( $label, $tree->cnt_host > 0 ? 'vspheredb/hosts' : ($tree->cnt_ds > 0 ? 'vspheredb/datastores' : 'vspheredb/vms'), Util::uuidParams($tree->uuid), $attributes - )); - } else { - $li->add(Html::tag('a', $attributes, $label)); - } + ) + : Html::tag('a', $attributes, $label); + + $li->add($link); } if ($hasChildren) { - $li->add( - $ul = Html::tag('ul') - ); + $li->add($ul = Html::tag('ul')); foreach ($tree->children as $child) { $ul->add($this->dumpTree($child, $level + 1)); } @@ -198,27 +170,22 @@ protected function dumpTree($tree, $level = 0) */ protected function getClassByType(string $type): string { - $typeClasses = [ - 'ComputeResource' => 'cubes', - 'ClusterComputeResource' => 'cubes', - 'Datacenter' => 'home', - 'DistributedVirtualPortgroup' => 'plug', - 'DistributedVirtualSwitch' => 'sitemap', + return 'icon-' . match ($type) { + 'ComputeResource', + 'ClusterComputeResource' => 'cubes', + 'Datacenter' => 'home', + 'DistributedVirtualPortgroup' => 'plug', + 'DistributedVirtualSwitch', 'VmwareDistributedVirtualSwitch' => 'sitemap', - 'Datastore' => 'database', - // 'DatastoreHostMount', - 'Folder' => 'folder-empty', - 'Network' => 'arrows-cw', - 'ResourcePool' => 'chart-pie', - 'StoragePod' => 'cloud', - 'HostSystem' => 'host', - 'VirtualApp' => 'th-thumb-empty', - 'VirtualMachine' => 'service', - ]; - if (isset($typeClasses[$type])) { - return 'icon-' . $typeClasses[$type]; - } else { - return 'icon-attention-alt'; - } + 'Datastore' => 'database', + 'Folder' => 'folder-empty', + 'Network' => 'arrows-cw', + 'ResourcePool' => 'chart-pie', + 'StoragePod' => 'cloud', + 'HostSystem' => 'host', + 'VirtualApp' => 'th-thumb-empty', + 'VirtualMachine' => 'service', + default => 'attention-alt' + }; } } diff --git a/library/Vspheredb/Web/QueryParams.php b/library/Vspheredb/Web/QueryParams.php index a77aee6f..54ca628b 100644 --- a/library/Vspheredb/Web/QueryParams.php +++ b/library/Vspheredb/Web/QueryParams.php @@ -7,9 +7,9 @@ class QueryParams { - protected $params; + protected array $params; - protected function __construct($params) + protected function __construct(array $params) { $this->params = $params; } @@ -19,24 +19,24 @@ public static function fromRequest(ServerRequestInterface $request): QueryParams return new static($request->getQueryParams()); } - public function has($key): bool + public function has(string $key): bool { - return \array_key_exists($key, $this->params); + return array_key_exists($key, $this->params); } /** * @param string $key - * @param $default + * @param mixed $default * - * @return mixed|null + * @return ?mixed */ - public function get(string $key, $default = null): mixed + public function get(string $key, mixed $default = null): mixed { if ($this->has($key)) { return $this->params[$key]; - } else { - return $default; } + + return $default; } /** @@ -48,8 +48,8 @@ public function getRequired(string $key): mixed { if ($this->has($key)) { return $this->params[$key]; - } else { - throw new InvalidArgumentException("Parameter '$key' is required"); } + + throw new InvalidArgumentException("Parameter '$key' is required"); } } diff --git a/library/Vspheredb/Web/Table/AlarmHistoryTable.php b/library/Vspheredb/Web/Table/AlarmHistoryTable.php index 2566a705..b02e6e8b 100644 --- a/library/Vspheredb/Web/Table/AlarmHistoryTable.php +++ b/library/Vspheredb/Web/Table/AlarmHistoryTable.php @@ -3,59 +3,55 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Date\DateFormatter; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class AlarmHistoryTable extends ZfQueryBasedTable { use UuidLinkHelper; - protected $entityUuid; + protected ?string $entityUuid = null; protected $defaultAttributes = [ 'class' => 'common-table', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - public function filterEntityUuid($uuid) + public function filterEntityUuid($uuid): static { $this->entityUuid = $uuid; return $this; } - public function renderRow($row) + public function renderRow($row): HtmlElement { $this->renderDayIfNew($row->ts_event_ms / 1000); - $content = [ - DateFormatter::formatTime($row->ts_event_ms / 1000), - ]; + $content = [DateFormatter::formatTime($row->ts_event_ms / 1000)]; if ($this->entityUuid === null) { $this->linkToUuid($row->entity_uuid); } $content[] = $row->full_message; - $tr = $this::row($content); - - return $tr; + return $this::row($content); } - protected function timeSince($ms) + + protected function timeSince(int $ms): ?string { return DateFormatter::timeAgo($ms); } - protected function prepareQuery() + protected function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from([ - 'ah' => 'alarm_history' - ])->order('ts_event_ms DESC'); + $query = $this->db()->select() + ->from(['ah' => 'alarm_history']) + ->order('ts_event_ms DESC'); if ($this->entityUuid === null) { - $query->join( - ['o' => 'object'], - 'o.uuid = ah.entity_uuid', - [] - ); + $query->join(['o' => 'object'], 'o.uuid = ah.entity_uuid', []); } else { $query->where('ah.entity_uuid = ?', $this->entityUuid); } diff --git a/library/Vspheredb/Web/Table/ArrayTable.php b/library/Vspheredb/Web/Table/ArrayTable.php index f5a620c2..7ae93a74 100644 --- a/library/Vspheredb/Web/Table/ArrayTable.php +++ b/library/Vspheredb/Web/Table/ArrayTable.php @@ -5,10 +5,13 @@ use gipfl\IcingaWeb2\Data\SimpleQueryPaginationAdapter; use gipfl\IcingaWeb2\Table\QueryBasedTable; use Icinga\Data\DataArray\ArrayDatasource; +use Icinga\Data\SimpleQuery; +use ipl\Html\HtmlElement; +use stdClass; class ArrayTable extends QueryBasedTable { - /** @var \stdClass */ + /** @var stdClass */ protected $rows; public function __construct($rows) @@ -17,27 +20,27 @@ public function __construct($rows) $this->getAttributes()->set('data-base-target', '_self'); } - public function renderRow($row) + public function renderRow($row): HtmlElement { return $this::row((array) $row); } - protected function getPaginationAdapter() + protected function getPaginationAdapter(): SimpleQueryPaginationAdapter { return new SimpleQueryPaginationAdapter($this->getQuery()); } - public function getQuery() + public function getQuery(): SimpleQuery { return $this->prepareQuery(); } - protected function fetchQueryRows() + protected function fetchQueryRows(): array { return $this->getQuery()->fetchAll(); } - protected function prepareQuery() + protected function prepareQuery(): SimpleQuery { return (new ArrayDatasource(array_values((array) $this->rows)))->select(); } diff --git a/library/Vspheredb/Web/Table/BaseTable.php b/library/Vspheredb/Web/Table/BaseTable.php index 09a2f073..8bec5031 100644 --- a/library/Vspheredb/Web/Table/BaseTable.php +++ b/library/Vspheredb/Web/Table/BaseTable.php @@ -8,34 +8,31 @@ use gipfl\IcingaWeb2\Url; use Icinga\Module\Vspheredb\Web\Widget\ToggleTableColumns; use InvalidArgumentException; +use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; use ipl\Html\HtmlElement; +use RuntimeException; abstract class BaseTable extends ZfQueryBasedTable { /** @var TableColumn[] */ - private $availableColumns = []; + private array $availableColumns = []; - /** @var TableColumn[] */ - private $chosenColumns; + /** @var ?TableColumn[] */ + private ?array $chosenColumns = null; - /** @var bool */ - private $isInitialized = false; + private ?bool $isInitialized = false; - /** @var Url */ - private $baseUrl; + private ?Url $baseUrl = null; - /** @var string */ - private $sortParam; + private ?string $sortParam = null; - /** @var array */ - private $sortColums = []; + private array $sortColums = []; - /** @var BaseHtmlElement|null */ - private $columnToggle; + private ?BaseHtmlElement $columnToggle = null; - protected $allowToCustomizeColumns = true; + protected bool $allowToCustomizeColumns = true; public function __construct($db, ?Url $url = null) { @@ -46,7 +43,7 @@ public function __construct($db, ?Url $url = null) } } - public function chooseColumns(array $columnNames) + public function chooseColumns(array $columnNames): static { $this->assertInitialized(); if ($columnNames === ['___ALL___']) { @@ -66,7 +63,7 @@ public function chooseColumns(array $columnNames) return $this; } - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): array { return $this->getChosenTitles(); } @@ -74,12 +71,12 @@ public function getColumnsToBeRendered() /** * @return TableColumn[] */ - public function getAvailableColumns() + public function getAvailableColumns(): array { return $this->availableColumns; } - public function hasColumn($name) + public function hasColumn(string $name): bool { return array_key_exists($name, $this->availableColumns); } @@ -95,15 +92,15 @@ public function getAvailableColumn(string $alias): TableColumn { if (array_key_exists($alias, $this->availableColumns)) { return $this->availableColumns[$alias]; - } else { - throw new InvalidArgumentException(sprintf('No column named "%s" is available', $alias)); } + + throw new InvalidArgumentException(sprintf('No column named "%s" is available', $alias)); } - public function assertInitialized() + public function assertInitialized(): void { if ($this->isInitialized === null) { - throw new \RuntimeException('Table initialization loop, this is a bug in your table'); + throw new RuntimeException('Table initialization loop, this is a bug in your table'); } if ($this->isInitialized === false) { $this->isInitialized = null; @@ -112,36 +109,33 @@ public function assertInitialized() } } - public function nextHeader() + public function nextHeader(): HtmlElement { - return parent::nextHeader()->setAttributes([ - 'data-base-target' => '_self' - ]); + return parent::nextHeader()->setAttributes(['data-base-target' => '_self']); } - protected function renderTitleColumns() + protected function renderTitleColumns(): ?HtmlElement { $columns = $this->getColumnsToBeRendered(); - if (isset($columns) && count($columns)) { + if (count($columns)) { if ($this->baseUrl) { - $tr = $this::tr()->setAttributes([ - 'data-base-target' => '_self' - ]); + $tr = $this::tr()->setAttributes(['data-base-target' => '_self']); $this->addSortHeadersTo($tr); } else { $tr = $this::row($columns, null, 'th'); } + return $tr; - } else { - return null; } + + return null; } - protected function initialize() + protected function initialize(): void { } - protected function getChosenColumns() + protected function getChosenColumns(): ?array { $this->assertInitialized(); // TODO: I do not want to call this: @@ -150,12 +144,12 @@ protected function getChosenColumns() return $this->chosenColumns; } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return array_keys($this->getAvailableColumns()); } - public function getChosenColumnNames() + public function getChosenColumnNames(): array { $this->assertInitialized(); if ($this->chosenColumns === null) { @@ -165,7 +159,7 @@ public function getChosenColumnNames() return array_keys($this->chosenColumns); } - protected function getChosenTitles() + protected function getChosenTitles(): array { $titles = []; @@ -176,14 +170,14 @@ protected function getChosenTitles() return $titles; } - protected function getRequiredDbColumns() + protected function getRequiredDbColumns(): array { $columns = []; foreach ($this->getChosenColumns() as $column) { foreach ($column->getRequiredDbColumns() as $alias => $dbExpression) { if (isset($columns[$alias]) && $columns[$alias] !== $dbExpression) { - throw new \RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Setting the same table alias twice, once for %s and once for %s', $columns[$alias], $dbExpression @@ -210,7 +204,7 @@ public function renderRow($row) return $tr; } - public function addAvailableColumn(TableColumn $column) + public function addAvailableColumn(TableColumn $column): static { $this->availableColumns[$column->getAlias()] = $column; @@ -219,9 +213,10 @@ public function addAvailableColumn(TableColumn $column) /** * @param TableColumn[] $columns + * * @return $this */ - public function addAvailableColumns($columns) + public function addAvailableColumns(array $columns): static { foreach ($columns as $column) { $this->addAvailableColumn($column); @@ -230,51 +225,47 @@ public function addAvailableColumns($columns) return $this; } - protected function createColumn($alias, $title = null, $column = null) - { + protected function createColumn( + string $alias, + ?string $title = null, + array|string|null $column = null + ): SimpleColumn { return new SimpleColumn($alias, $title, $column); } /** * @param Url $url * @param string $sortParam + * * @return $this */ - public function handleUrl(Url $url, $sortParam = 'sort') + public function handleUrl(Url $url, string $sortParam = 'sort'): static { if ($this->isInitialized) { - throw new \RuntimeException('Sort Url is late'); + throw new RuntimeException('Sort Url is late'); } $this->assertInitialized(); $this->prepareColumnToggle($url); $this->sortParam = $sortParam; $this->baseUrl = $url; - $sort = $url->getParam($sortParam); - if (null === $sort) { - $this->sortBy($this->getDefaultSortColumns()); - } else { - $this->sortBy($sort); - } + $this->sortBy($url->getParam($sortParam) ?? $this->getDefaultColumnNames()); return $this; } - protected function getDefaultSortColumns() + protected function getDefaultSortColumns(): array|string { - $columns = $this->getChosenColumnNames(); - return $columns[0]; + return $this->getChosenColumnNames()[0]; } /** - * @param string|array $columns + * @param array|string $columns + * * @return $this */ - public function sortBy($columns) + public function sortBy(array|string $columns): static { - if ($columns === null) { - return $this; - } $this->assertInitialized(); if (! is_array($columns)) { $columns = [$columns]; @@ -306,11 +297,11 @@ public function sortBy($columns) return $this; } - protected function addSortIcon(TableColumn $column, BaseHtmlElement $element) + protected function addSortIcon(TableColumn $column, BaseHtmlElement $element): BaseHtmlElement { $icons = [ 'ASC' => 'up-dir', - 'DESC' => 'down-dir', + 'DESC' => 'down-dir' ]; if (array_key_exists($column->getAlias(), $this->sortColums)) { $element->add(Icon::create($icons[$this->sortColums[$column->getAlias()]])); @@ -319,7 +310,7 @@ protected function addSortIcon(TableColumn $column, BaseHtmlElement $element) return $element; } - protected function getNextSortLinkString(TableColumn $column) + protected function getNextSortLinkString(TableColumn $column): string { $string = $column->getAlias(); if (array_key_exists($column->getAlias(), $this->sortColums)) { @@ -333,18 +324,19 @@ protected function getNextSortLinkString(TableColumn $column) if ($column->getDefaultSortDirection() === 'ASC') { return $string; - } else { - return "$string DESC"; } + + return "$string DESC"; } /** * TODO: we should consider introducing TablePlugins for similar tasks * * @param HtmlElement $parent + * * @return HtmlElement */ - protected function addSortHeadersTo(HtmlElement $parent) + protected function addSortHeadersTo(HtmlElement $parent): HtmlElement { // Hint: MUST be set $url = $this->baseUrl; @@ -365,13 +357,13 @@ protected function addSortHeadersTo(HtmlElement $parent) if ($this->columnToggle !== null && $lastTh !== null) { $lastTh->add(Html::tag('ul', ['class' => 'nav'], $this->columnToggle)); - $lastTh->addAttributes(['class' => 'with-column-selector']); + $lastTh->addAttributes(Attributes::create(['class' => 'with-column-selector'])); } return $parent; } - protected function prepareColumnToggle($url) + protected function prepareColumnToggle(Url $url): void { if ($this->allowToCustomizeColumns) { $this->columnToggle = (new ToggleTableColumns($this, $url))->ensureAssembled(); diff --git a/library/Vspheredb/Web/Table/ControlSocketConnectionsTable.php b/library/Vspheredb/Web/Table/ControlSocketConnectionsTable.php index e668fa7b..fa59e66d 100644 --- a/library/Vspheredb/Web/Table/ControlSocketConnectionsTable.php +++ b/library/Vspheredb/Web/Table/ControlSocketConnectionsTable.php @@ -3,12 +3,14 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Icon; +use ipl\Html\Attributes; +use ipl\Html\HtmlElement; class ControlSocketConnectionsTable extends ArrayTable { protected $searchColumns = [ 'username', - 'socket', + 'socket' ]; /* Sample Row: @@ -31,7 +33,7 @@ class ControlSocketConnectionsTable extends ArrayTable } */ - protected $myPid; + protected int $myPid; public function __construct($rows) { @@ -39,15 +41,13 @@ public function __construct($rows) $this->myPid = posix_getpid(); } - public function renderRow($row) + public function renderRow($row): HtmlElement { $tr = $this::row([ [ - $row->direction === 'in' ? Icon::create('endtime', [ - 'title' => $this->translate('Incoming connection'), - ]) : Icon::create('starttime', [ - 'title' => $this->translate('Outgoing connection'), - ]), + $row->direction === 'in' + ? Icon::create('endtime', ['title' => $this->translate('Incoming connection')]) + : Icon::create('starttime', ['title' => $this->translate('Outgoing connection')]), ' ', $row->socket ], @@ -55,18 +55,18 @@ public function renderRow($row) $row->pid ]); if ($row->pid === $this->myPid) { - $tr->addAttributes(['class' => 'control-socket-connections-table-row']); + $tr->addAttributes(Attributes::create(['class' => 'control-socket-connections-table-row'])); } return $tr; } - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): array { return [ $this->translate('Socket'), $this->translate('User'), - $this->translate('Client PID'), + $this->translate('Client PID') ]; } } diff --git a/library/Vspheredb/Web/Table/Dependency/DependencyInfoTable.php b/library/Vspheredb/Web/Table/Dependency/DependencyInfoTable.php deleted file mode 100644 index c27688a7..00000000 --- a/library/Vspheredb/Web/Table/Dependency/DependencyInfoTable.php +++ /dev/null @@ -1,101 +0,0 @@ -module = $module; - $this->checker = $checker; - } - - protected function linkToModule($name, $icon) - { - return Html::link( - Html::escape($name), - Html::webUrl('config/module', ['name' => $name]), - [ - 'class' => "icon-$icon" - ] - ); - } - - public function render() - { - $html = ' - - - - - - - - -'; - foreach ($this->checker->getDependencies($this->module) as $dependency) { - $name = $dependency->getName(); - $isLibrary = substr($name, 0, 11) === 'icinga-php-'; - $rowAttributes = $isLibrary ? ['data-base-target' => '_self'] : null; - if ($dependency->isSatisfied()) { - if ($dependency->isSatisfied()) { - $icon = 'ok'; - } else { - $icon = 'cancel'; - } - $link = $isLibrary ? $this->noLink($name, $icon) : $this->linkToModule($name, $icon); - $installed = $dependency->getInstalledVersion(); - } elseif ($dependency->isInstalled()) { - $installed = sprintf('%s (%s)', $dependency->getInstalledVersion(), $this->translate('disabled')); - $link = $this->linkToModule($name, 'cancel'); - } else { - $installed = $this->translate('missing'); - $repository = $isLibrary ? $name : "icingaweb2-module-$name"; - $link = sprintf( - '%s (%s)', - $this->noLink($name, 'cancel'), - Html::linkToGitHub(Html::escape($this->translate('more')), 'Icinga', $repository) - ); - } - - $html .= $this->htmlRow([ - $link, - Html::escape($dependency->getRequirement()), - Html::escape($installed) - ], $rowAttributes); - } - - return $html . ' -
' . Html::escape($this->translate('Module name')) . '' . Html::escape($this->translate('Required')) . '' . Html::escape($this->translate('Installed')) . '
-'; - } - - protected function noLink($label, $icon) - { - return Html::link(Html::escape($label), Url::fromRequest()->with('rnd', rand(1, 100000)), [ - 'class' => "icon-$icon" - ]); - } - - protected function translate($string) - { - return \mt('director', $string); - } - - protected function htmlRow(array $cols, $rowAttributes) - { - $content = ''; - foreach ($cols as $escapedContent) { - $content .= Html::tag('td', null, $escapedContent); - } - return Html::tag('tr', $rowAttributes, $content); - } -} diff --git a/library/Vspheredb/Web/Table/Dependency/Html.php b/library/Vspheredb/Web/Table/Dependency/Html.php deleted file mode 100644 index b66deb73..00000000 --- a/library/Vspheredb/Web/Table/Dependency/Html.php +++ /dev/null @@ -1,74 +0,0 @@ - $value) { - if (! preg_match('/^[a-z][a-z0-9:-]*$/i', $name)) { - throw new InvalidArgumentException("Invalid attribute name: '$name'"); - } - - $result .= " $name=\"" . self::escapeAttributeValue($value) . '"'; - } - } - - return "$result>$escapedContent"; - } - - public static function webUrl($path, $params) - { - return Url::fromPath($path, $params); - } - - public static function link($escapedLabel, $url, $attributes = []) - { - return static::tag('a', [ - 'href' => $url, - ] + $attributes, $escapedLabel); - } - - public static function linkToGitHub($escapedLabel, $namespace, $repository) - { - return static::link( - $escapedLabel, - 'https://github.com/' . urlencode($namespace) . '/' . urlencode($repository), - [ - 'target' => '_blank', - 'rel' => 'noreferrer', - 'class' => 'icon-forward' - ] - ); - } - - protected static function escapeAttributeValue($value) - { - $value = str_replace('"', '"', $value); - // Escape ambiguous ampersands - return preg_replace_callback('/&[0-9A-Z]+;/i', function ($match) { - $subject = $match[0]; - - if (htmlspecialchars_decode($subject, ENT_COMPAT | ENT_HTML5) === $subject) { - // Ambiguous ampersand - return str_replace('&', '&', $subject); - } - - return $subject; - }, $value); - } - - public static function escape($any) - { - return htmlspecialchars($any); - } -} diff --git a/library/Vspheredb/Web/Table/EventHistoryTable.php b/library/Vspheredb/Web/Table/EventHistoryTable.php index baf03acd..0d36b099 100644 --- a/library/Vspheredb/Web/Table/EventHistoryTable.php +++ b/library/Vspheredb/Web/Table/EventHistoryTable.php @@ -11,33 +11,37 @@ use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\Util; +use ipl\Html\Attributes; use ipl\Html\DeferredText; +use ipl\Html\FormattedString; use ipl\Html\Html; use ipl\Html\HtmlDocument; +use ipl\Html\HtmlElement; use ipl\Html\HtmlString; use ipl\Html\Text; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Select; class EventHistoryTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => ['common-table', 'event-history-table'], - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - protected $requiredUuids = []; + protected array $requiredUuids = []; - protected $vMotionEvents = [ + protected array $vMotionEvents = [ 'VmFailedMigrateEvent', 'MigrationEvent', 'VmBeingMigratedEvent', 'VmBeingHotMigratedEvent', 'VmEmigratingEvent', - 'VmMigratedEvent', + 'VmMigratedEvent' ]; - protected $otherKnownEvents = [ + protected array $otherKnownEvents = [ 'VmStartingEvent', 'VmPoweredOnEvent', 'VmStoppingEvent', @@ -54,24 +58,19 @@ class EventHistoryTable extends ZfQueryBasedTable 'VmCloneFailedEvent' ]; - protected $fetchedUuids; + protected ?array $fetchedUuids = null; - /** @var Datastore */ - protected $datastore; + protected ?Datastore $datastore = null; - /** @var HostSystem */ - protected $host; + protected ?HostSystem $host = null; - /** @var VirtualMachine */ - protected $vm; + protected ?VirtualMachine $vm = null; - /** @var string */ - protected $eventType; + protected string|array|null $eventType = null; - /** @var ?UuidInterface */ - protected $parent; + protected ?UuidInterface $parent = null; - public function renderRow($row) + public function renderRow($row): HtmlElement { $this->renderDayIfNew($row->ts_event_ms / 1000); $content = []; @@ -96,113 +95,57 @@ public function renderRow($row) } elseif (in_array($row->event_type, $this->otherKnownEvents)) { $content[] = new HtmlString(nl2br(new Text($row->full_message))); } - $tr = $this::row([ - $content, - DateFormatter::formatTime($row->ts_event_ms / 1000) - ]); - - switch ($row->event_type) { - case 'VmFailedMigrateEvent': - case 'VmBeingClonedNoFolderEvent': - case 'VmCloneFailedEvent': - $tr->addAttributes([ - 'class' => 'state migration-failed', - ]); - break; - case 'DrsVmMigratedEvent': - case 'VmMigratedEvent': - $tr->addAttributes([ - 'class' => 'state migrated', - ]); - break; - case 'VmBeingMigratedEvent': - case 'VmBeingHotMigratedEvent': - $tr->addAttributes([ - 'class' => 'state migrating', - ]); - break; - case 'VmEmigratingEvent': - $tr->addAttributes([ - 'class' => 'state emigrating', - ]); - break; - case 'VmResettingEvent': - case 'VmPoweredOffEvent': - $tr->addAttributes([ - 'class' => 'state poweredOff', - ]); - break; - case 'VmStartingEvent': - $tr->addAttributes([ - 'class' => 'state starting', - ]); - break; - case 'VmPoweredOnEvent': - $tr->addAttributes([ - 'class' => 'state poweredOn', - ]); - break; - case 'VmStoppingEvent': - $tr->addAttributes([ - 'class' => 'state stopping', - ]); - break; - case 'VmSuspendedEvent': - $tr->addAttributes([ - 'class' => 'event suspended', - ]); - break; - case 'VmReconfiguredEvent': - case 'VmClonedEvent': - case 'VmBeingClonedEvent': - $tr->addAttributes([ - 'class' => 'event reconfigured', - ]); - break; - case 'VmBeingCreatedEvent': - case 'VmBeingDeployedEvent': - $tr->addAttributes([ - 'class' => 'event being-created', - ]); - break; - case 'VmCreatedEvent': - $tr->addAttributes([ - 'class' => 'event created', - ]); - break; - default: - $tr->add($this::td(Html::tag('pre', null, print_r($row, 1)))); + $tr = $this::row([$content, DateFormatter::formatTime($row->ts_event_ms / 1000)]); + + $class = match ($row->event_type) { + 'VmFailedMigrateEvent', 'VmBeingClonedNoFolderEvent', 'VmCloneFailedEvent' => 'state migration-failed', + 'DrsVmMigratedEvent', 'VmMigratedEvent' => 'state migrated', + 'VmBeingMigratedEvent', 'VmBeingHotMigratedEvent' => 'state migrating', + 'VmEmigratingEvent' => 'state emigrating', + 'VmResettingEvent', 'VmPoweredOffEvent' => 'state poweredOff', + 'VmStartingEvent' => 'state starting', + 'VmPoweredOnEvent' => 'state poweredOn', + 'VmStoppingEvent' => 'state stopping', + 'VmSuspendedEvent' => 'event suspended', + 'VmReconfiguredEvent', 'VmClonedEvent', 'VmBeingClonedEvent' => 'event reconfigured', + 'VmBeingCreatedEvent', 'VmBeingDeployedEvent' => 'event being-created', + 'VmCreatedEvent' => 'event created', + default => null + }; + + if ($class !== null) { + $tr->addAttributes(Attributes::create(['class' => $class])); + } else { + $tr->add($this::td(Html::tag('pre', null, print_r($row, 1)))); } - $tr->addAttributes([ - 'title' => sprintf('%s (%s)', $row->full_message, $row->event_type) - ]); - - return $tr; + return $tr->addAttributes( + Attributes::create(['title' => sprintf('%s (%s)', $row->full_message, $row->event_type)]) + ); } - public function filterVm(VirtualMachine $vm) + public function filterVm(VirtualMachine $vm): static { $this->vm = $vm; return $this; } - public function filterHost(HostSystem $host) + public function filterHost(HostSystem $host): static { $this->host = $host; return $this; } - public function filterDatastore(Datastore $datastore) + public function filterDatastore(Datastore $datastore): static { $this->datastore = $datastore; return $this; } - public function filterEventType($type) + public function filterEventType(string|array|null $type): static { if (is_array($type)) { $this->eventType = $type; @@ -213,7 +156,7 @@ public function filterEventType($type) return $this; } - public function filterParent($uuid) + public function filterParent(?string $uuid): static { if ($uuid !== null && strlen($uuid)) { $this->parent = Uuid::fromString($uuid); @@ -239,12 +182,12 @@ protected function getUuidName(?string $uuid): string if (array_key_exists($uuid, $this->fetchedUuids)) { return $this->fetchedUuids[$uuid]; - } else { - return '[UNKNOWN]'; } + + return '[UNKNOWN]'; } - protected function fetchUuidNames() + protected function fetchUuidNames(): void { $db = $this->db(); if (empty($this->requiredUuids)) { @@ -260,30 +203,30 @@ protected function fetchUuidNames() ); } - protected function timeSince($ms) + protected function timeSince(int $ms): ?string { return DateFormatter::timeAgo($ms); } /** - * @return \Zend_Db_Select + * @return Zend_Db_Select */ - protected function prepareQuery() + protected function prepareQuery(): Zend_Db_Select { - $query = $this->db()->select()->from([ - 'vh' => 'vm_event_history' - ], [ - 'vh.ts_event_ms', - 'vh.event_type', - 'vh.vm_uuid', - 'vh.host_uuid', - 'vh.user_name', - 'vh.datastore_uuid', - 'vh.destination_host_uuid', - 'vh.destination_datastore_uuid', - 'vh.full_message', - 'vh.fault_reason', - ])->order('ts_event_ms DESC'); + $query = $this->db()->select() + ->from(['vh' => 'vm_event_history'], [ + 'vh.ts_event_ms', + 'vh.event_type', + 'vh.vm_uuid', + 'vh.host_uuid', + 'vh.user_name', + 'vh.datastore_uuid', + 'vh.destination_host_uuid', + 'vh.destination_datastore_uuid', + 'vh.full_message', + 'vh.fault_reason' + ]) + ->order('ts_event_ms DESC'); if (is_string($this->eventType) && strlen($this->eventType)) { $query->where('event_type = ?', $this->eventType); @@ -294,8 +237,8 @@ protected function prepareQuery() if ($this->parent !== null) { $query->join( ['o' => 'object'], - '(o.uuid = vh.vm_uuid OR o.uuid = vh.host_uuid OR o.uuid = vh.datastore_uuid)' - . ' AND o.parent_uuid = ' . DbUtil::quoteBinaryCompat($this->parent->getBytes(), $this->db()), + '(o.uuid = vh.vm_uuid OR o.uuid = vh.host_uuid OR o.uuid = vh.datastore_uuid) AND o.parent_uuid = ' + . DbUtil::quoteBinaryCompat($this->parent->getBytes(), $this->db()), [] ); } @@ -317,13 +260,13 @@ protected function prepareQuery() return $query; } - protected function deferredVMotionPath($row) + protected function deferredVMotionPath(object $row): DeferredText { $properties = [ 'host_uuid', 'destination_host_uuid', 'datastore_uuid', - 'destination_datastore_uuid', + 'destination_datastore_uuid' ]; foreach ($properties as $property) { if ($row->$property !== null) { @@ -331,11 +274,7 @@ protected function deferredVMotionPath($row) } } - $content = new DeferredText(function () use ($row) { - return $this->showMotionPath($row); - }); - - return $content->setEscaped(); + return (new DeferredText(fn() => $this->showMotionPath($row)))->setEscaped(); } /** @@ -347,18 +286,15 @@ protected function deferredObjectName(?string $uuid): DeferredText { $this->requiredUuids[$uuid ?? ''] = $uuid; - $content = new DeferredText(function () use ($uuid) { - return $this->getUuidName($uuid); - }); - - return $content->setEscaped(); + return (new DeferredText(fn() => $this->getUuidName($uuid)))->setEscaped(); } /** - * @param $row + * @param object $row + * * @return HtmlDocument */ - protected function showMotionPath($row) + protected function showMotionPath(object $row): HtmlDocument { $html = new HtmlDocument(); if ($row->host_uuid !== $row->destination_host_uuid) { @@ -393,10 +329,11 @@ protected function showMotionPath($row) } /** - * @param $row - * @return \ipl\Html\FormattedString + * @param object $row + * + * @return FormattedString */ - protected function showHostToHostMigration($row) + protected function showHostToHostMigration(object $row): FormattedString { if ($row->event_type === 'VmEmigratingEvent') { return Html::sprintf( @@ -408,29 +345,30 @@ protected function showHostToHostMigration($row) ), Icon::create('right-big') ); - } else { - return Html::sprintf( - '%s %s %s', - Link::create( - $this->getUuidName($row->host_uuid), - 'vspheredb/host', - ['uuid' => Util::niceUuid($row->host_uuid)] - ), - Icon::create('right-big'), - Link::create( - $this->getUuidName($row->destination_host_uuid), - 'vspheredb/host', - ['uuid' => Util::niceUuid($row->destination_host_uuid)] - ) - ); } + + return Html::sprintf( + '%s %s %s', + Link::create( + $this->getUuidName($row->host_uuid), + 'vspheredb/host', + ['uuid' => Util::niceUuid($row->host_uuid)] + ), + Icon::create('right-big'), + Link::create( + $this->getUuidName($row->destination_host_uuid), + 'vspheredb/host', + ['uuid' => Util::niceUuid($row->destination_host_uuid)] + ) + ); } /** - * @param $row - * @return \ipl\Html\FormattedString + * @param object $row + * + * @return FormattedString */ - protected function showDatastoreToDatastoreMigration($row) + protected function showDatastoreToDatastoreMigration(object $row): FormattedString { return Html::sprintf( '%s %s %s', @@ -449,10 +387,11 @@ protected function showDatastoreToDatastoreMigration($row) } /** - * @param $row - * @return \ipl\Html\FormattedString + * @param object $row + * + * @return FormattedString */ - protected function showToDatastoreMigration($row) + protected function showToDatastoreMigration(object $row): FormattedString { return Html::sprintf( '%s %s', @@ -466,10 +405,11 @@ protected function showToDatastoreMigration($row) } /** - * @param $row - * @return \ipl\Html\FormattedString + * @param object $row + * + * @return FormattedString */ - protected function showFromDatastoreMigration($row) + protected function showFromDatastoreMigration(object $row): FormattedString { return Html::sprintf( '%s %s', @@ -483,10 +423,11 @@ protected function showFromDatastoreMigration($row) } /** - * @param $row - * @return \ipl\Html\FormattedString + * @param object $row + * + * @return FormattedString */ - protected function showToHostMigration($row) + protected function showToHostMigration(object $row): FormattedString { return Html::sprintf( '%s %s', @@ -500,10 +441,11 @@ protected function showToHostMigration($row) } /** - * @param $row - * @return \ipl\Html\FormattedString + * @param object $row + * + * @return FormattedString */ - protected function showFromHostMigration($row) + protected function showFromHostMigration(object $row): FormattedString { return Html::sprintf( '%s %s', diff --git a/library/Vspheredb/Web/Table/HostHbaTable.php b/library/Vspheredb/Web/Table/HostHbaTable.php index f972e01f..b231c90d 100644 --- a/library/Vspheredb/Web/Table/HostHbaTable.php +++ b/library/Vspheredb/Web/Table/HostHbaTable.php @@ -3,23 +3,24 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\DbObject\HostSystem; -use Icinga\Module\Vspheredb\Format; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; +use ipl\Html\FormattedString; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class HostHbaTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => 'common-table', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - /** @var HostSystem */ - protected $host; + protected HostSystem $host; - /** @var string */ - protected $moref; + protected ?string $moref = null; public function __construct(HostSystem $host) { @@ -27,7 +28,7 @@ public function __construct(HostSystem $host) $this->moref = $this->host->object()->get('moref'); parent::__construct($host->getConnection()); - $this->prepend(new SubTitle(\sprintf( + $this->prepend(new SubTitle(sprintf( $this->translate('HBA (%s)'), // Hint: we could also count given HBAs, but this helps to spot // eventual inconsistencies @@ -35,7 +36,7 @@ public function __construct(HostSystem $host) ), 'sitemap')); } - public function renderRow($row) + public function renderRow($row): HtmlElement { $attributes = []; if ($row->status !== 'online') { @@ -45,7 +46,7 @@ public function renderRow($row) return $this::row([$this->formatSimple($row)], $attributes); } - protected function formatSimple($row) + protected function formatSimple(object $row): FormattedString { return Html::sprintf( '%s (%s: %s), %s: %s', @@ -57,20 +58,10 @@ protected function formatSimple($row) ); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['hh' => 'host_hba'], - [ - 'hh.hba_key', - 'hh.device', - 'hh.driver', - 'hh.status', - 'hh.model', - 'hh.pci', - ] - )->where('hh.host_uuid = ?', $this->host->get('uuid'))->order('hh.device ASC'); - - return $query; + return $this->db()->select() + ->from(['hh' => 'host_hba'], ['hh.hba_key', 'hh.device', 'hh.driver', 'hh.status', 'hh.model', 'hh.pci']) + ->where('hh.host_uuid = ?', $this->host->get('uuid'))->order('hh.device ASC'); } } diff --git a/library/Vspheredb/Web/Table/HostPciDevicesTable.php b/library/Vspheredb/Web/Table/HostPciDevicesTable.php index 34ece0f8..19b5dcfd 100644 --- a/library/Vspheredb/Web/Table/HostPciDevicesTable.php +++ b/library/Vspheredb/Web/Table/HostPciDevicesTable.php @@ -3,13 +3,16 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\DbObject\HostSystem; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class HostPciDevicesTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => 'common-table', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; protected $searchColumns = [ @@ -18,37 +21,36 @@ class HostPciDevicesTable extends ZfQueryBasedTable 'device_name' ]; - /** @var HostSystem */ - protected $host; + protected ?HostSystem $host = null; - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): array { return [ $this->translate('ID'), - $this->translate('Device (Vendor)'), + $this->translate('Device (Vendor)') ]; } - public function renderRow($row) + public function renderRow($row): HtmlElement { return static::row([ $row->id, - sprintf('%s (%s)', $row->device_name, $row->vendor_name), + sprintf('%s (%s)', $row->device_name, $row->vendor_name) ]); } - public function filterHost(HostSystem $host) + public function filterHost(HostSystem $host): static { $this->host = $host; return $this; } - protected function prepareQuery() + protected function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from([ - 'hpd' => 'host_pci_device' - ])->order('id ASC')->limit(1000); + $query = $this->db()->select() + ->from(['hpd' => 'host_pci_device']) + ->order('id ASC')->limit(1000); if ($this->host) { $query->where('host_uuid = ?', $this->host->get('uuid')); diff --git a/library/Vspheredb/Web/Table/HostPhysicalNicTable.php b/library/Vspheredb/Web/Table/HostPhysicalNicTable.php index 1fbfccac..8e90501f 100644 --- a/library/Vspheredb/Web/Table/HostPhysicalNicTable.php +++ b/library/Vspheredb/Web/Table/HostPhysicalNicTable.php @@ -3,25 +3,27 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Data\Anonymizer; use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\Format; use Icinga\Module\Vspheredb\Web\Widget\MacAddress; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; +use ipl\Html\FormattedString; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class HostPhysicalNicTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => 'common-table', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - /** @var HostSystem */ - protected $host; + protected HostSystem $host; - /** @var string */ - protected $moref; + protected ?string $moref = null; public function __construct(HostSystem $host) { @@ -29,7 +31,7 @@ public function __construct(HostSystem $host) $this->moref = $this->host->object()->get('moref'); parent::__construct($host->getConnection()); - $this->prepend(new SubTitle(\sprintf( + $this->prepend(new SubTitle(sprintf( $this->translate('Network Interfaces (%s)'), // Hint: we could also count given NICs, but this helps to spot // eventual inconsistencies @@ -37,7 +39,7 @@ public function __construct(HostSystem $host) ), 'sitemap')); } - public function renderRow($row) + public function renderRow($row): HtmlElement { $attributes = []; if ($row->link_speed_mb === null) { @@ -46,12 +48,12 @@ public function renderRow($row) return $this::row([$this->formatSimple($row)], $attributes); } - protected function formatSimple($row) + protected function formatSimple(object $row): FormattedString { if ($row->link_speed_mb === null) { $speedInfo = $this->translate('Link is down'); } else { - $speedInfo = \sprintf( + $speedInfo = sprintf( '%s %s', Format::linkSpeedMb($row->link_speed_mb), $row->link_duplex === 'y' @@ -70,11 +72,10 @@ protected function formatSimple($row) ); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['hpn' => 'host_physical_nic'], - [ + return $this->db()->select() + ->from(['hpn' => 'host_physical_nic'], [ 'hpn.nic_key', 'hpn.auto_negotiate_supported', 'hpn.device', @@ -82,10 +83,8 @@ public function prepareQuery() 'hpn.link_speed_mb', 'hpn.link_duplex', 'hpn.mac_address', - 'hpn.pci', - ] - )->where('hpn.host_uuid = ?', $this->host->get('uuid'))->order('hpn.device ASC'); - - return $query; + 'hpn.pci' + ]) + ->where('hpn.host_uuid = ?', $this->host->get('uuid'))->order('hpn.device ASC'); } } diff --git a/library/Vspheredb/Web/Table/HostSensorsTable.php b/library/Vspheredb/Web/Table/HostSensorsTable.php index dedb5796..d175dbe8 100644 --- a/library/Vspheredb/Web/Table/HostSensorsTable.php +++ b/library/Vspheredb/Web/Table/HostSensorsTable.php @@ -7,40 +7,42 @@ use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; use Icinga\Module\Vspheredb\DbObject\HostSystem; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class HostSensorsTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => 'common-table sensors-table', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; protected $searchColumns = [ 'name', - 'sensor_type', + 'sensor_type' ]; - /** @var HostSystem */ - protected $host; + protected ?HostSystem $host = null; - protected $lastType; + protected ?string $lastType = null; - protected $summaries; + protected ?array $summaries = null; - public function renderRow($row) + public function renderRow($row): HtmlElement { $this->renderTypeIfNew($row->sensor_type); + return static::row([ $this->renderHealthState($row->health_state), $row->name, - $this->renderCurrentMeasurement($row), + $this->renderCurrentMeasurement($row) ]); } /** - * @param $type + * @param string $type */ - protected function renderTypeIfNew($type) + protected function renderTypeIfNew(string $type): void { if ($this->lastType !== $type) { $summary = $this->getSummaryByType($type); @@ -54,10 +56,7 @@ protected function renderTypeIfNew($type) } $this->nextHeader()->add( - $this::th($title, [ - 'colspan' => 3, - 'class' => 'table-header-day' - ]) + $this::th($title, ['colspan' => 3, 'class' => 'table-header-day']) ); $this->lastType = $type; @@ -65,7 +64,7 @@ protected function renderTypeIfNew($type) } } - protected function makeHealthStateBadge($state, $count) + protected function makeHealthStateBadge(string $state, int $count): Link { return Link::create($count, '#', null, ['class' => ['state', $state]]); } @@ -84,26 +83,21 @@ protected function getSummaryByType(string $type): array return $this->summaries[$type]; } - protected function renderHealthState($state) + protected function renderHealthState(string $state): Icon { - switch ($state) { - case 'green': - return Icon::create('ok', ['class' => ['state', $state]]); - case 'red': - case 'yellow': - return Icon::create('attention-alt', ['class' => ['state', $state]]); - case 'unknown': - return Icon::create('help', ['class' => ['state gray']]); - default: - return $state; - } + return match ($state) { + 'green' => Icon::create('ok', ['class' => ['state', $state]]), + 'red', 'yellow' => Icon::create('attention-alt', ['class' => ['state', $state]]), + 'unknown' => Icon::create('help', ['class' => ['state gray']]), + default => $state + }; } public function renderSummaries() { } - protected function renderCurrentMeasurement($row) + protected function renderCurrentMeasurement(object $row): string { if ($row->base_units === null) { return '-'; @@ -116,7 +110,7 @@ protected function renderCurrentMeasurement($row) ); } - public function filterHost(HostSystem $host) + public function filterHost(HostSystem $host): static { $this->host = $host; @@ -126,22 +120,24 @@ public function filterHost(HostSystem $host) /** * @return array */ - public function fetchSummaries() + public function fetchSummaries(): array { // Well... ROLLUP would help. $db = $this->db(); $sums = []; - $query = $db->select()->from(['hs' => 'host_sensor'], [ - 'sensor_type' => 'sensor_type', - 'health_state' => 'health_state', - 'cnt' => 'COUNT(*)', - ]) + $query = $db->select() + ->from(['hs' => 'host_sensor'], [ + 'sensor_type' => 'sensor_type', + 'health_state' => 'health_state', + 'cnt' => 'COUNT(*)' + ]) ->where('base_units IS NOT NULL') ->group('sensor_type') ->group('health_state') ->order('sensor_type') ->order('health_state'); + if ($this->host) { $query->where('host_uuid = ?', $this->host->get('uuid')); } @@ -154,7 +150,7 @@ public function fetchSummaries() 'green' => 0, 'yellow' => 0, 'unknown' => 0, - 'red' => 0, + 'red' => 0 ]; } @@ -165,16 +161,17 @@ public function fetchSummaries() } /** - * @return \Zend_Db_Select + * @return Zend_Db_Select */ - protected function prepareQuery() + protected function prepareQuery(): Zend_Db_Select { - $query = $this->db()->select()->from([ - 'hpd' => 'host_sensor' - ])->order('sensor_type')->order('name')->limit(1000); - - $query->where('base_units IS NOT NULL'); - // $query->where('health_state != ?', 'unknown'); + $query = $this->db()->select() + ->from(['hpd' => 'host_sensor']) + ->order('sensor_type') + ->order('name') + ->limit(1000) + ->where('base_units IS NOT NULL'); + // ->where('health_state != ?', 'unknown'); if ($this->host) { $query->where('host_uuid = ?', $this->host->get('uuid')); diff --git a/library/Vspheredb/Web/Table/MonitoredObjectMappingTable.php b/library/Vspheredb/Web/Table/MonitoredObjectMappingTable.php index 03dd8ffe..37d13fcf 100644 --- a/library/Vspheredb/Web/Table/MonitoredObjectMappingTable.php +++ b/library/Vspheredb/Web/Table/MonitoredObjectMappingTable.php @@ -4,104 +4,88 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\Extension\ZfSortablePriority; +use gipfl\ZfDb\Select; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use Zend_Db_Select; class MonitoredObjectMappingTable extends BaseTable { use ZfSortablePriority; - protected $keyColumn = 'id'; + protected string $keyColumn = 'id'; - protected $priorityColumn = 'priority'; + protected string $priorityColumn = 'priority'; protected $defaultAttributes = [ 'class' => ['common-table', 'table-row-selectable'], - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ (new SimpleColumn('source', $this->translate('Source'), [ 'source_type' => 'mc.source_type', 'source_resource_name' => 'mc.source_resource_name', 'id' => 'mc.id', - 'priority' => 'mc.priority', - ]))->setRenderer(function ($row) { - return Link::create(sprintf( - '%s: %s', - $row->source_type, - $row->source_resource_name - ), 'vspheredb/configuration/monitoringconfig', [ - 'id' => $row->id - ], [ - 'data-base-target' => '_next' - ]); - }), + 'priority' => 'mc.priority' + ])) + ->setRenderer(fn($row) => Link::create( + sprintf('%s: %s', $row->source_type, $row->source_resource_name), + 'vspheredb/configuration/monitoringconfig', + ['id' => $row->id], + ['data-base-target' => '_next'] + )), + (new SimpleColumn('host_mapping', $this->translate('Host Mapping'), [ 'host_property' => 'mc.host_property', - 'monitoring_host_property' => 'mc.monitoring_host_property', - ]))->setRenderer(function ($row) { - if ($row->host_property === null) { - return null; - } else { - return sprintf( - '%s -> %s', - $row->monitoring_host_property, - $row->host_property - ); - } - }), + 'monitoring_host_property' => 'mc.monitoring_host_property' + ])) + ->setRenderer(fn($row) => $row->host_property === null ? null : sprintf( + '%s -> %s', + $row->monitoring_host_property, + $row->host_property + )), + (new SimpleColumn('vm_mapping', $this->translate('VM Mapping'), [ 'vm_property' => 'mc.vm_property', - 'monitoring_vm_host_property' => 'mc.monitoring_vm_host_property', - ]))->setRenderer(function ($row) { - if ($row->host_property === null) { - return null; - } else { - return sprintf( - '%s -> %s', - $row->monitoring_vm_host_property, - $row->vm_property - ); - } - }), + 'monitoring_vm_host_property' => 'mc.monitoring_vm_host_property' + ])) + ->setRenderer(fn($row) => $row->host_property === null ? null : sprintf( + '%s -> %s', + $row->monitoring_vm_host_property, + $row->vm_property + )) ]); } // cloned from ZfSortablePriority, added data-base-target - protected function xaddSortPriorityButtons(BaseHtmlElement $tr, $row) + protected function xaddSortPriorityButtons(BaseHtmlElement $tr, object $row): BaseHtmlElement { - $tr->add( + return $tr->add( Html::tag( 'td', ['data-base-target' => '_self'], $this->createUpDownButtons($row->{$this->getKeyColumn()}) ) ); - - return $tr; } - public function renderRow($row) + public function renderRow($row): BaseHtmlElement { - return $this->xaddSortPriorityButtons( - parent::renderRow($row), - $row - ); + return $this->xaddSortPriorityButtons(parent::renderRow($row), $row); } - public function render() + public function render(): string { return $this->renderWithSortableForm(); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - ['mc' => 'monitoring_connection'], - $this->getRequiredDbColumns() - )->order('priority'); + return $this->db()->select() + ->from(['mc' => 'monitoring_connection'], $this->getRequiredDbColumns()) + ->order('priority'); } } diff --git a/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemHistoryTable.php b/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemHistoryTable.php index 275edfde..33d7d2be 100644 --- a/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemHistoryTable.php +++ b/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemHistoryTable.php @@ -4,6 +4,7 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\Data\Anonymizer; use Icinga\Module\Vspheredb\Db\DbUtil; @@ -13,26 +14,28 @@ use Icinga\Module\Vspheredb\Web\Table\UuidLinkHelper; use Icinga\Module\Vspheredb\Web\Widget\CheckPluginHelper; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class MonitoringRuleProblemHistoryTable extends ZfQueryBasedTable implements TableWithVCenterFilter { use UuidLinkHelper; - protected $entityUuid; + protected ?string $entityUuid = null; protected $defaultAttributes = [ 'class' => ['common-table', 'table-row-selectable'], - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - public function filterEntityUuid($uuid) + public function filterEntityUuid(string $uuid): static { $this->entityUuid = $uuid; return $this; } - public function renderRow($row) + public function renderRow($row): HtmlElement { $this->renderDayIfNew($row->ts_changed_ms / 1000); @@ -41,7 +44,7 @@ public function renderRow($row) $output = [ CheckPluginHelper::colorizeOutput($this->translate('[OK] Check has no longer been executed')), ' ', - CheckPluginHelper::colorizeOutput($formerState), + CheckPluginHelper::colorizeOutput($formerState) ]; } else { $lines = preg_split("/\r?\n/", $row->output); @@ -49,26 +52,23 @@ public function renderRow($row) $output = CheckPluginHelper::colorizeOutput(implode("\n", $lines)); } - if ($this->entityUuid) { - $cell[] = Html::tag('strong', $row->rule_name); - } else { - $cell[] = Html::sprintf( + $cell[] = $this->entityUuid + ? Html::tag('strong', $row->rule_name) + : Html::sprintf( $this->translate("%s on %s"), Html::tag('strong', $row->rule_name), $this->linkToObject($row) // No link if entityUuid!! ); - } $cell[] = "\n"; $cell[] = $output; - $tr = $this::row([Html::tag('pre', [ - 'class' => 'logOutput' - ], $cell), DateFormatter::formatTime($row->ts_changed_ms / 1000)]); - - return $tr; + return $this::row([ + Html::tag('pre', ['class' => 'logOutput'], $cell), + DateFormatter::formatTime($row->ts_changed_ms / 1000) + ]); } - protected function linkToObject($row) + protected function linkToObject($row): Link { return Link::create( Anonymizer::anonymizeString($row->object_name), @@ -79,37 +79,30 @@ protected function linkToObject($row) protected function getBaseUrl($row): ?string { - switch ($row->object_type) { - case 'HostSystem': - return 'vspheredb/host'; - case 'VirtualMachine': - return 'vspheredb/vm'; - case 'Datastore': - return 'vspheredb/datastore'; - default: - return null; - } + return match ($row->object_type) { + 'HostSystem' => 'vspheredb/host', + 'VirtualMachine' => 'vspheredb/vm', + 'Datastore' => 'vspheredb/datastore', + default => null + }; } - protected function prepareQuery() + protected function prepareQuery(): Select|Zend_Db_Select { // uuid, current_state, former_state, rule_name, ts_changed_ms, output - $query = $this->db()->select()->from([ - 'ph' => 'monitoring_rule_problem_history' - ], [ - 'o.object_name', - 'o.object_type', - 'ph.uuid', - 'ph.current_state', - 'ph.former_state', - 'ph.rule_name', - 'ph.ts_changed_ms', - 'ph.output', - ])->join( - ['o' => 'object'], - 'o.uuid = ph.uuid', - [] - )->order('ts_changed_ms DESC'); + $query = $this->db()->select() + ->from(['ph' => 'monitoring_rule_problem_history'], [ + 'o.object_name', + 'o.object_type', + 'ph.uuid', + 'ph.current_state', + 'ph.former_state', + 'ph.rule_name', + 'ph.ts_changed_ms', + 'ph.output' + ]) + ->join(['o' => 'object'], 'o.uuid = ph.uuid', []) + ->order('ts_changed_ms DESC'); if ($this->entityUuid !== null) { $query->where('ph.uuid = ?', $this->entityUuid); @@ -118,15 +111,16 @@ protected function prepareQuery() return $query; } - public function filterVCenter(VCenter $vCenter): self + public function filterVCenter(VCenter $vCenter): static { return $this->filterVCenterUuids([$vCenter->getUuid()]); } - public function filterVCenterUuids(array $uuids): self + public function filterVCenterUuids(array $uuids): static { if (empty($uuids)) { $this->getQuery()->where('1 = 0'); + return $this; } diff --git a/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemTable.php b/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemTable.php index eea972be..60131b25 100644 --- a/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemTable.php +++ b/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblemTable.php @@ -4,25 +4,27 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Db\DbUtil; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\Util; use Icinga\Module\Vspheredb\Web\Table\TableWithVCenterFilter; use ipl\Html\Html; +use Zend_Db_Select; class MonitoringRuleProblemTable extends ZfQueryBasedTable implements TableWithVCenterFilter { - protected $formerVCenter = null; + protected ?string $formerVCenter = null; public function getColumnsToBeRendered(): array { return [ $this->translate('VCenter'), - $this->translate('Problems / Monitoring Rule'), + $this->translate('Problems / Monitoring Rule') ]; } - public function renderRow($row) + public function renderRow($row): array { if ($row->vcenter_name === $this->formerVCenter) { $row->vcenter_name = null; @@ -37,10 +39,7 @@ public function renderRow($row) if (! empty($states)) { $states[] = ' '; } - $states[] = Html::tag('span', ['class' => [ - 'badge', - "state-$state" - ]], $row->$property); + $states[] = Html::tag('span', ['class' => ['badge', "state-$state"]], $row->$property); } unset($row->$property); } @@ -56,22 +55,23 @@ public function renderRow($row) 'vcenter' => Util::niceUuid($row->vcenter_uuid), 'objectType' => $objectType, 'ruleSet' => $ruleSet, - 'rule' => $rule, + 'rule' => $rule ])]; unset($row->vcenter_uuid); return (array) $row; } - public function filterVCenter(VCenter $vCenter): self + public function filterVCenter(VCenter $vCenter): static { return $this->filterVCenterUuids([$vCenter->getUuid()]); } - public function filterVCenterUuids(array $uuids): self + public function filterVCenterUuids(array $uuids): static { if (empty($uuids)) { $this->getQuery()->where('1 = 0'); + return $this; } @@ -86,30 +86,26 @@ public function filterVCenterUuids(array $uuids): self return $this; } - protected function prepareQuery() + protected function prepareQuery(): Select|Zend_Db_Select { - $db = $this->db(); - return $db->select()->from( - ['p' => 'monitoring_rule_problem'], - [ - 'vcenter_uuid' => 'vc.instance_uuid', - 'vcenter_name' => 'vc.name', + return $this->db()->select() + ->from(['p' => 'monitoring_rule_problem'], [ + 'vcenter_uuid' => 'vc.instance_uuid', + 'vcenter_name' => 'vc.name', // 'object_type' => 'o.object_type', // 'rule_name' => 'p.rule_name', 'object_rule_name' => "o.object_type || '/' || p.rule_name", - 'cnt_critical' => "SUM(CASE WHEN p.current_state = 'CRITICAL' THEN 1 ELSE 0 END)", - 'cnt_unknown' => "SUM(CASE WHEN p.current_state = 'UNKNOWN' THEN 1 ELSE 0 END)", - 'cnt_warning' => "SUM(CASE WHEN p.current_state = 'WARNING' THEN 1 ELSE 0 END)", - ] - ) - ->join(['o' => 'object'], 'o.uuid = p.uuid', []) - ->join(['vc' => 'vcenter'], 'o.vcenter_uuid = vc.instance_uuid', []) + 'cnt_critical' => "SUM(CASE WHEN p.current_state = 'CRITICAL' THEN 1 ELSE 0 END)", + 'cnt_unknown' => "SUM(CASE WHEN p.current_state = 'UNKNOWN' THEN 1 ELSE 0 END)", + 'cnt_warning' => "SUM(CASE WHEN p.current_state = 'WARNING' THEN 1 ELSE 0 END)" + ]) + ->join(['o' => 'object'], 'o.uuid = p.uuid', []) + ->join(['vc' => 'vcenter'], 'o.vcenter_uuid = vc.instance_uuid', []) ->group('vc.name') ->group('o.object_type') ->group('p.rule_name') ->order('vc.name') ->order('o.object_type') - ->order('p.rule_name') - ; + ->order('p.rule_name'); } } diff --git a/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblematicObjectTable.php b/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblematicObjectTable.php index 9e9ed03e..988f22ed 100644 --- a/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblematicObjectTable.php +++ b/library/Vspheredb/Web/Table/Monitoring/MonitoringRuleProblematicObjectTable.php @@ -4,25 +4,32 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; +use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Db\DbUtil; +use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\Monitoring\CheckRunner; -use Icinga\Module\Vspheredb\Monitoring\MonitoringRuleLookup; +use Icinga\Module\Vspheredb\Monitoring\Rule\Enum\ObjectType; use Icinga\Module\Vspheredb\Web\Widget\CheckPluginHelper; use ipl\Html\Html; use ipl\Html\HtmlString; use Ramsey\Uuid\Uuid; +use Zend_Db_Select; class MonitoringRuleProblematicObjectTable extends ZfQueryBasedTable { - protected $objectType; - protected $ruleSet; - protected $rule; - /** @var CheckRunner */ - protected $runner; - protected $vCenter; + protected string $objectType; - public function __construct($db, $vCenter, $objectType, $ruleSet, $rule) + protected string $ruleSet; + + protected string $rule; + + protected CheckRunner $runner; + + protected VCenter $vCenter; + + public function __construct(Db $db, Vcenter $vCenter, string $objectType, string $ruleSet, string $rule) { parent::__construct($db); $this->objectType = $objectType; @@ -36,15 +43,14 @@ public function __construct($db, $vCenter, $objectType, $ruleSet, $rule) public function getColumnsToBeRendered(): array { - return [ - $this->translate('Object'), - ]; + return [$this->translate('Object')]; } - public function renderRow($row) + public function renderRow($row): array { - $url = MonitoringRuleLookup::getUrlForObjectType($this->objectType); - $class = MonitoringRuleLookup::getClassForObjectType($this->objectType); + $type = ObjectType::fromParam($this->objectType); + $url = $type->url(); + $class = $type->class(); $object = $class::load($row->uuid, $this->connection()); $result = $this->runner->check($object); @@ -55,34 +61,30 @@ public function renderRow($row) } } - $link = Link::create($label, $url, [ - 'uuid' => Uuid::fromBytes($row->uuid)->toString() - ]); + $link = Link::create($label, $url, ['uuid' => Uuid::fromBytes($row->uuid)->toString()]); $output = $result->getOutput(); $output = explode(PHP_EOL, $output); - $output[0] = $output[0] . ': ' . 'LINK!TO!OBJECT'; + $output[0] .= ': LINK!TO!OBJECT'; $output = CheckPluginHelper::colorizeOutput(implode(PHP_EOL, $output))->render(); $output = preg_replace('/LINK!TO!OBJECT/', $link->render(), $output); - $output = new HtmlString($output); - return [[ - Html::tag('pre', ['class' => 'logOutput'], $output) - ]]; + return [[Html::tag('pre', ['class' => 'logOutput'], new HtmlString($output))]]; } - protected function prepareQuery() + protected function prepareQuery(): Select|Zend_Db_Select { - $objectTable = MonitoringRuleLookup::getTableForObjectType($this->objectType); + $objectTable = ObjectType::fromParam($this->objectType)->table(); $db = $this->db(); - return $db->select()->from(['p' => 'monitoring_rule_problem'], [ - 'uuid' => 'o.uuid', - 'rule_name' => 'p.rule_name', - ]) - ->where('o.vcenter_uuid = ?', DbUtil::quoteBinaryCompat($this->vCenter->get('uuid'), $db)) - ->where('p.rule_name = ?', sprintf('%s/%s', $this->ruleSet, $this->rule)) - ->join(['o' => 'object'], 'o.uuid = p.uuid', []) - ->join(['ot' => $objectTable], 'o.uuid = ot.uuid', []) - ->order('p.current_state DESC') - ->order('o.object_name'); + return $db->select() + ->from(['p' => 'monitoring_rule_problem'], [ + 'uuid' => 'o.uuid', + 'rule_name' => 'p.rule_name' + ]) + ->where('o.vcenter_uuid = ?', DbUtil::quoteBinaryCompat($this->vCenter->get('uuid'), $db)) + ->where('p.rule_name = ?', sprintf('%s/%s', $this->ruleSet, $this->rule)) + ->join(['o' => 'object'], 'o.uuid = p.uuid', []) + ->join(['ot' => $objectTable], 'o.uuid = ot.uuid', []) + ->order('p.current_state DESC') + ->order('o.object_name'); } } diff --git a/library/Vspheredb/Web/Table/Object/HostHardwareInfoTable.php b/library/Vspheredb/Web/Table/Object/HostHardwareInfoTable.php index 1427c4ec..d0a2b1e3 100644 --- a/library/Vspheredb/Web/Table/Object/HostHardwareInfoTable.php +++ b/library/Vspheredb/Web/Table/Object/HostHardwareInfoTable.php @@ -15,11 +15,9 @@ class HostHardwareInfoTable extends NameValueTable { use Translation; - /** @var HostSystem */ - protected $host; + protected HostSystem $host; - /** @var HostQuickStats */ - protected $quickStats; + protected HostQuickStats $quickStats; public function __construct(HostSystem $host, HostQuickStats $quickStats) { @@ -27,13 +25,13 @@ public function __construct(HostSystem $host, HostQuickStats $quickStats) $this->quickStats = $quickStats; } - protected function assemble() + protected function assemble(): void { $this->prepend(new SubTitle($this->translate('Hardware Information'), 'th-thumb-empty')); $host = $this->host; $this->addNameValuePairs([ $this->translate('CPU') => [ - \sprintf( + sprintf( $this->translate('%d Packages, %d Cores, %d Threads'), $host->get('hardware_cpu_packages'), $host->get('hardware_cpu_cores'), @@ -50,7 +48,7 @@ protected function assemble() $this->quickStats->get('overall_memory_usage_mb'), $host->get('hardware_memory_size_mb') ), - $this->translate('HBAs') => $host->get('hardware_num_hba'), + $this->translate('HBAs') => $host->get('hardware_num_hba') ]); } } diff --git a/library/Vspheredb/Web/Table/Object/HostSystemInfoTable.php b/library/Vspheredb/Web/Table/Object/HostSystemInfoTable.php index 8d758fb4..514ec95b 100644 --- a/library/Vspheredb/Web/Table/Object/HostSystemInfoTable.php +++ b/library/Vspheredb/Web/Table/Object/HostSystemInfoTable.php @@ -15,20 +15,18 @@ use Icinga\Module\Vspheredb\Web\Widget\Link\MobLink; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\I18n\Translation; class HostSystemInfoTable extends NameValueTable { use Translation; - /** @var HostSystem */ - protected $host; + protected HostSystem $host; - /** @var HostQuickStats */ - protected $quickStats; + protected HostQuickStats $quickStats; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(HostSystem $host, HostQuickStats $quickStats, VCenter $vCenter) { @@ -37,7 +35,7 @@ public function __construct(HostSystem $host, HostQuickStats $quickStats, VCente $this->vCenter = $vCenter; } - protected function assemble() + protected function assemble(): void { $this->prepend(new SubTitle($this->translate('System Information'), 'host')); $host = $this->host; @@ -52,45 +50,46 @@ protected function assemble() $this->translate('Service Tag') => $this->getFormattedServiceTag($host), $this->translate('BIOS Version') => new BiosInfo($host), $this->translate('Uptime') => $this->showUptime($this->quickStats->get('uptime')), - $this->translate('System UUID') => Html::tag('pre', Anonymizer::shuffleString($host->get('sysinfo_uuid'))), + $this->translate('System UUID') => Html::tag('pre', Anonymizer::shuffleString($host->get('sysinfo_uuid'))) ]); } - protected function showUptime($uptime) + protected function showUptime($uptime): array { return [ DateFormatter::formatDuration($uptime), $uptime < 900 ? Icon::create('warning-empty', [ 'class' => ['state', 'yellow'], - 'title' => $this->translate('System booted recently'), - ]) : null, + 'title' => $this->translate('System booted recently') + ]) : null ]; } /** * @param HostSystem $host - * @return \ipl\Html\HtmlElement|mixed + * + * @return HtmlElement|mixed */ - protected function getFormattedServiceTag(HostSystem $host) + protected function getFormattedServiceTag(HostSystem $host): mixed { if ($tag = $host->get('service_tag')) { $tag = Anonymizer::shuffleString($tag); } if ($this->host->get('sysinfo_vendor') === 'Dell Inc.') { return $this->linkToDellSupport($tag); - } else { - return $tag; } + + return $tag; } - protected function prepareTools(HostSystem $host) + protected function prepareTools(HostSystem $host): Hint|array { $tools = []; if ($this->vCenter->getFirstServer(false, false) === null) { return Hint::warning($this->translate('There is no configured connection for this vCenter')); } - if (\version_compare($this->vCenter->get('api_version'), '6.5', '>=')) { + if (version_compare($this->vCenter->get('api_version'), '6.5', '>=')) { $tools[] = new Html5UiLink($this->vCenter, $host, 'HTML5 UI'); $tools[] = ' '; } @@ -99,7 +98,7 @@ protected function prepareTools(HostSystem $host) return $tools; } - protected function renderVendorModel($vendor, $model) + protected function renderVendorModel(?string $vendor, ?string $model): array|string|null { if ($url = $this->findVendorModel($vendor, $model)) { if (is_array($url)) { @@ -134,9 +133,9 @@ protected function renderVendorModel($vendor, $model) * @param ?string $vendor * @param ?string $model * - * @return ?string + * @return array|string|null */ - protected function findVendorModel(?string $vendor, ?string $model): ?string + protected function findVendorModel(?string $vendor, ?string $model): array|string|null { $images = include __DIR__ . '/known-vendor-model-images.php'; if ($vendor === null || $model === null) { @@ -147,7 +146,7 @@ protected function findVendorModel(?string $vendor, ?string $model): ?string } if (isset($images[$vendor])) { foreach ($images[$vendor] as $pattern => $url) { - if (substr($pattern, 0, 1) === '/' && preg_match($pattern, $model)) { + if (str_starts_with($pattern, '/') && preg_match($pattern, $model)) { return $url; } } @@ -156,27 +155,22 @@ protected function findVendorModel(?string $vendor, ?string $model): ?string return null; } - protected function linkToDellSupport($serviceTag) + protected function linkToDellSupport(?string $serviceTag): HtmlElement|string { if ($serviceTag === null) { return '-'; } - $urlPattern = 'http://www.dell.com/support/home/product-support/servicetag/%s/drivers'; - - $url = sprintf( - $urlPattern, - strtolower($serviceTag) - ); - - return Html::tag( - 'a', - [ - 'href' => $url, - 'target' => '_blank', - 'title' => $this->translate('Dell Support Page'), - 'rel' => 'noreferrer' - ], - $serviceTag - ); + + $attributes = [ + 'href' => sprintf( + 'http://www.dell.com/support/home/product-support/servicetag/%s/drivers', + strtolower($serviceTag) + ), + 'target' => '_blank', + 'title' => $this->translate('Dell Support Page'), + 'rel' => 'noreferrer' + ]; + + return Html::tag('a', $attributes, $serviceTag); } } diff --git a/library/Vspheredb/Web/Table/Object/HostVirtualizationInfoTable.php b/library/Vspheredb/Web/Table/Object/HostVirtualizationInfoTable.php index 008c4c8d..34ad40f2 100644 --- a/library/Vspheredb/Web/Table/Object/HostVirtualizationInfoTable.php +++ b/library/Vspheredb/Web/Table/Object/HostVirtualizationInfoTable.php @@ -17,15 +17,15 @@ class HostVirtualizationInfoTable extends NameValueTable { use Translation; - /** @var HostSystem */ - protected $host; + protected HostSystem $host; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; /** * HostVirtualizationInfoTable constructor. + * * @param HostSystem $host + * * @throws NotFoundError */ public function __construct(HostSystem $host) @@ -34,7 +34,7 @@ public function __construct(HostSystem $host) $this->vCenter = VCenter::load($host->get('vcenter_uuid'), $host->getConnection()); } - protected function assemble() + protected function assemble(): void { $this->prepend(new SubTitle($this->translate('Virtualization Information'), 'cloud')); $host = $this->host; @@ -43,14 +43,14 @@ protected function assemble() $this->addNameValuePairs([ $this->translate('vCenter') => new VCenterLink($this->vCenter), $this->translate('Path') => PathToObjectRenderer::render($host), - $this->translate('Vms') => Link::create( + $this->translate('Vms') => Link::create( $host->countVms(), 'vspheredb/host/vms', Util::uuidParams($uuid) ), $this->translate('HA State') => $host->get('das_host_state'), $this->translate('Hypervisor') => $host->get('product_full_name'), - $this->translate('API Version') => $host->get('product_api_version'), + $this->translate('API Version') => $host->get('product_api_version') ]); } } diff --git a/library/Vspheredb/Web/Table/Object/HostVmsInfoTable.php b/library/Vspheredb/Web/Table/Object/HostVmsInfoTable.php deleted file mode 100644 index 3e913881..00000000 --- a/library/Vspheredb/Web/Table/Object/HostVmsInfoTable.php +++ /dev/null @@ -1,42 +0,0 @@ -host = $host; - $this->prepend(new SubTitle($this->translate('Virtual Machines'), 'cubes')); - } - - protected function getDb() - { - return $this->host->getConnection(); - } - - protected function assemble() - { - $host = $this->host; - $uuid = $host->get('uuid'); - $this->addNameValuePairs([ - $this->translate('Vms') => Link::create( - $host->countVms(), - 'vspheredb/host/vms', - Util::uuidParams($uuid) - ), - ]); - } -} diff --git a/library/Vspheredb/Web/Table/Object/VCenterInfoTable.php b/library/Vspheredb/Web/Table/Object/VCenterInfoTable.php deleted file mode 100644 index 69132a4b..00000000 --- a/library/Vspheredb/Web/Table/Object/VCenterInfoTable.php +++ /dev/null @@ -1,47 +0,0 @@ -vcenter = $vcenter; - } - - protected function assemble() - { - $c = $this->vcenter; - - $this->addNameValuePairs([ - $this->translate('Name') => $c->get('name'), - $this->translate('Info') => sprintf( - '%s %s build-%s', - $c->get('api_type'), - $c->get('version'), - $c->get('build') - ), - $this->translate('UUID') => Uuid::fromBytes($c->get('instance_uuid'))->toString(), - // $this->translate('Version') => $c->get('version'), - $this->translate('OS Type') => $c->get('os_type'), - $this->translate('API Type') => $c->get('api_type'), - $this->translate('API Version') => $c->get('api_version'), - // $this->translate('Build') => $c->get('build'), - $this->translate('Vendor') => $c->get('vendor'), - $this->translate('Product Line') => $c->get('product_line'), - $this->translate('license Product Name') => $c->get('license_product_name'), - $this->translate('license Product Version') => $c->get('license_product_version'), - $this->translate('Locale Build') => $c->get('locale_build'), - $this->translate('Locale Version') => $c->get('locale_version'), - ]); - } -} diff --git a/library/Vspheredb/Web/Table/Object/VmEssentialInfoTable.php b/library/Vspheredb/Web/Table/Object/VmEssentialInfoTable.php index 5c9ee762..ea8e0382 100644 --- a/library/Vspheredb/Web/Table/Object/VmEssentialInfoTable.php +++ b/library/Vspheredb/Web/Table/Object/VmEssentialInfoTable.php @@ -2,18 +2,19 @@ namespace Icinga\Module\Vspheredb\Web\Table\Object; +use Exception; use gipfl\IcingaWeb2\Icon; use gipfl\IcingaWeb2\Link; use ipl\I18n\Translation; use gipfl\Web\Table\NameValueTable; -use Exception; use gipfl\Web\Widget\Hint; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\Addon\IbmSpectrumProtect; -use Icinga\Module\Vspheredb\Addon\SimpleBackupTool; use Icinga\Module\Vspheredb\Addon\NetBackup; +use Icinga\Module\Vspheredb\Addon\SimpleBackupTool; use Icinga\Module\Vspheredb\Addon\VeeamBackup; use Icinga\Module\Vspheredb\Addon\VRangerBackup; +use Icinga\Module\Vspheredb\Db\DbConnection; use Icinga\Module\Vspheredb\DbObject\MonitoringConnection; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; @@ -28,16 +29,15 @@ use Icinga\Module\Vspheredb\Web\Widget\Renderer\GuestToolsVersionRenderer; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; use ipl\Html\Html; +use ipl\Html\HtmlElement; class VmEssentialInfoTable extends NameValueTable { use Translation; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VirtualMachine $vm) { @@ -46,22 +46,23 @@ public function __construct(VirtualMachine $vm) $this->vCenter = VCenter::load($vm->get('vcenter_uuid'), $vm->getConnection()); } - protected function getDb() + protected function getDb(): ?DbConnection { return $this->vm->getConnection(); } /** - * @param $annotation - * @return string|\ipl\Html\HtmlElement + * @param string $annotation + * + * @return string|HtmlElement */ - protected function formatAnnotation($annotation) + protected function formatAnnotation(string $annotation): HtmlElement|string { $tools = [ new IbmSpectrumProtect(), new NetBackup(), new VeeamBackup(), - new VRangerBackup(), + new VRangerBackup() ]; foreach ($tools as $tool) { if ($tool instanceof SimpleBackupTool) { @@ -71,26 +72,19 @@ protected function formatAnnotation($annotation) $annotation = trim($annotation); - if (strpos($annotation, "\n") === false) { + if (! str_contains($annotation, "\n")) { return $annotation; - } else { - return Html::tag('pre', null, $annotation); } + + return Html::tag('pre', null, $annotation); } - /** - * @throws \Icinga\Exception\NotFoundError - */ - protected function assemble() + protected function assemble(): void { $vm = $this->vm; - $uuid = $vm->get('uuid'); $this->addNameValueRow($this->translate('Tools'), $this->prepareTools($vm)); if ($annotation = $vm->get('annotation')) { - $this->addNameValueRow( - $this->translate('Annotation'), - $this->formatAnnotation($annotation) - ); + $this->addNameValueRow($this->translate('Annotation'), $this->formatAnnotation($annotation)); } if ($guestName = $vm->get('guest_full_name')) { @@ -119,8 +113,8 @@ protected function assemble() $this->translate('Guest Hostname') => $vm->get('guest_host_name') ?: '-', $this->translate('Guest IP') => $vm->get('guest_ip_address') ?: '-', $this->translate('Guest OS') => $guest, - $this->translate('Guest Utilities') => $guestInfo, - // $this->translate('Test') => $this->getMonitoringInfo($vm), + $this->translate('Guest Utilities') => $guestInfo + // $this->translate('Test') => $this->getMonitoringInfo($vm) ]); $quickStats = VmQuickStats::loadFor($vm); if ($vm->get('runtime_power_state') === 'poweredOn') { @@ -131,8 +125,8 @@ protected function assemble() DateFormatter::formatDuration($uptime), $uptime < 900 ? Icon::create('warning-empty', [ 'class' => ['state', 'yellow'], - 'title' => $this->translate('System booted recently'), - ]) : null, + 'title' => $this->translate('System booted recently') + ]) : null ] ); } @@ -147,13 +141,13 @@ protected function assemble() Link::create( $this->translate('VMotion attempt(s)'), 'vspheredb/vm/events', - Util::uuidParams($uuid) + Util::uuidParams($vm->get('uuid')) ) ) ); } - protected function prepareTools(VirtualMachine $vm) + protected function prepareTools(VirtualMachine $vm): Hint|array { $tools = []; @@ -163,7 +157,7 @@ protected function prepareTools(VirtualMachine $vm) } $tools[] = new VmrcLink($this->vCenter, $vm, 'VMRC'); $tools[] = ' '; - if (\version_compare($this->vCenter->get('api_version'), '6.5', '>=')) { + if (version_compare($this->vCenter->get('api_version'), '6.5', '>=')) { $tools[] = new Html5UiLink($this->vCenter, $vm, 'HTML5 UI'); $tools[] = ' '; } @@ -172,7 +166,7 @@ protected function prepareTools(VirtualMachine $vm) return $tools; } - protected function getGuestToolsVersionInfo($vm) + protected function getGuestToolsVersionInfo(VirtualMachine $vm): string|array { $info = $vm->get('guest_tools_version'); if ($info === null) { @@ -190,8 +184,7 @@ protected function getGuestToolsVersionInfo($vm) ) )]; } else { - $renderer = new GuestToolsVersionRenderer(); - $info = $renderer($info); + $info = (new GuestToolsVersionRenderer())($info); } return $info; @@ -199,9 +192,10 @@ protected function getGuestToolsVersionInfo($vm) /** * @param VirtualMachine $vm - * @return array|null + * + * @return array */ - protected function getMonitoringInfo(VirtualMachine $vm) + protected function getMonitoringInfo(VirtualMachine $vm): array { $name = $vm->get('guest_host_name'); $statusRenderer = new IcingaHostStatusRenderer(); @@ -222,11 +216,9 @@ protected function getMonitoringInfo(VirtualMachine $vm) ['class' => 'icon-right-small'] ) ]; - } else { - return [Html::sprintf( - "There is no monitored Host mapped to this VM" - )]; } + + return [Html::sprintf("There is no monitored Host mapped to this VM")]; } catch (Exception $e) { return [ Hint::error( diff --git a/library/Vspheredb/Web/Table/Object/VmExtraInfoTable.php b/library/Vspheredb/Web/Table/Object/VmExtraInfoTable.php index 5ff0d234..079a7a3d 100644 --- a/library/Vspheredb/Web/Table/Object/VmExtraInfoTable.php +++ b/library/Vspheredb/Web/Table/Object/VmExtraInfoTable.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Vspheredb\Web\Table\Object; use gipfl\Web\Table\NameValueTable; +use Icinga\Module\Vspheredb\Db\DbConnection; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; @@ -13,11 +14,9 @@ class VmExtraInfoTable extends NameValueTable { use Translation; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VirtualMachine $vm) { @@ -26,23 +25,18 @@ public function __construct(VirtualMachine $vm) $this->vCenter = VCenter::load($vm->get('vcenter_uuid'), $vm->getConnection()); } - protected function getDb() + protected function getDb(): ?DbConnection { return $this->vm->getConnection(); } - /** - * @throws \Icinga\Exception\NotFoundError - */ - protected function assemble() + protected function assemble(): void { - $vm = $this->vm; - $this->addNameValuePairs([ - $this->translate('UUID') => Html::tag('pre', $vm->get('bios_uuid')), - $this->translate('Instance UUID') => Html::tag('pre', $vm->get('instance_uuid')), - $this->translate('CPUs') => $vm->get('hardware_numcpu'), - $this->translate('Version') => $vm->get('version'), + $this->translate('UUID') => Html::tag('pre', $this->vm->get('bios_uuid')), + $this->translate('Instance UUID') => Html::tag('pre', $this->vm->get('instance_uuid')), + $this->translate('CPUs') => $this->vm->get('hardware_numcpu'), + $this->translate('Version') => $this->vm->get('version') ]); } } diff --git a/library/Vspheredb/Web/Table/Object/VmLiveCountersTable.php b/library/Vspheredb/Web/Table/Object/VmLiveCountersTable.php deleted file mode 100644 index dde454cc..00000000 --- a/library/Vspheredb/Web/Table/Object/VmLiveCountersTable.php +++ /dev/null @@ -1,163 +0,0 @@ -vm = $vm; - $this->api = $api; - } - - protected function getDb() - { - return $this->vm->getConnection(); - } - - protected function assemble() - { - $this->addLiveCounters(); - } - - protected function addLiveCounters() - { - $vm = $this->vm; - $uuid = $vm->get('uuid'); - - $info = [ - 526 => 'Data receive rate', - 527 => 'Data transmit rate', - 543 => 'Read Latency', - 544 => 'Write Latency', - 171 => 'Average Read/s', - 172 => 'Average Write/s', - ]; - - $units = [ - 526 => 'kByte/s', - 527 => 'kByte/s', - 543 => 'µs', - 544 => 'µs', - 171 => 'average reads/s', - 172 => 'average writes/s', - ]; - - try { - $interval = 20; - $someData = $this->fetchSomePerfdata($interval); - $someData = $someData[0]; - Benchmark::measure('Got data from vCenter'); - $times = array_values( - array_filter( - preg_split('/,/', $someData->sampleInfoCSV), - function ($val) use ($interval) { - return $val !== (string) $interval; - } - ) - ); - - $first = new DateTime(array_shift($times)); - $last = new DateTime(array_pop($times)); - $first = (int) $first->format('U') * 1000; - $last = (int) $last->format('U') * 1000; - foreach ($someData->value as $data) { - $this->addNameValueRow( - sprintf( - '%s (%s)', - $data->id->instance, - $info[$data->id->counterId ?? ''] - ), - [ - Html::tag('span', [ - 'class' => 'sparkline overspark', - 'sparkType' => 'line', - 'data-first' => $first, - 'data-last' => $last, - 'data-interval' => $interval, - 'values' => $data->value - ]), - Html::tag('span', [ - 'class' => 'sparkinfo' - ]), - Html::tag('span', null, ' ' . $units[$data->id->counterId ?? '']) - ] - ); - } - } catch (Exception $e) { - $this->addNameValueRow('ERROR', $e->getMessage()); - } - foreach ($this->fetchPerf($uuid) as $instance => $perf) { - $this->addNameValueRow($instance, $perf); - } - } - - protected function fetchPerf($uuid) - { - $db = $this->getDb()->getDbAdapter(); - - $values = implode(" || ',' || ", [ - 'value_minus4', - 'value_minus3', - 'value_minus2', - 'value_minus1', - 'value_last', - ]); - - $query = $db->select()->from('counter_300x5', [ - 'instance', - 'counter_key', - 'value' => $values, - ])->where('object_uuid = ?', $uuid) - ->where('counter_key IN (?)', [171, 172, 526, 527]) - ->order('counter_key')->order('instance'); - - $rows = $db->fetchAll($query); - - $result = []; - /** @var object{instance: string, counter_key: int, value: string} $row */ - foreach ($rows as $row) { - $result[$row->instance][$row->counter_key] = $row->value; - } - - $final = []; - - foreach ($result as $instance => $entries) { - $in = array_shift($entries); - $out = array_shift($entries); - $final[$instance] = new CompactInOutSparkline($in, $out); - } - - return $final; - } - - protected function fetchSomePerfdata($interval) - { - $raw = $this->api->perfManager()->oldTestQueryPerf( - $this->vm->object()->get('moref'), - 'VirtualMachine', - $interval, - 600 - ); - - return $raw->returnval; - } -} diff --git a/library/Vspheredb/Web/Table/Object/VmLocationInfoTable.php b/library/Vspheredb/Web/Table/Object/VmLocationInfoTable.php index fbe11393..9ec0ef88 100644 --- a/library/Vspheredb/Web/Table/Object/VmLocationInfoTable.php +++ b/library/Vspheredb/Web/Table/Object/VmLocationInfoTable.php @@ -5,6 +5,8 @@ use gipfl\Web\Table\NameValueTable; use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Data\Anonymizer; +use Icinga\Module\Vspheredb\Db; +use Icinga\Module\Vspheredb\Db\DbConnection; use Icinga\Module\Vspheredb\DbObject\HostQuickStats; use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VCenter; @@ -18,17 +20,16 @@ use Icinga\Module\Vspheredb\Web\Widget\Renderer\PathToObjectRenderer; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\I18n\Translation; class VmLocationInfoTable extends NameValueTable { use Translation; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VirtualMachine $vm, VCenter $vCenter) { @@ -37,15 +38,15 @@ public function __construct(VirtualMachine $vm, VCenter $vCenter) $this->vCenter = $vCenter; } - protected function getDb() + protected function getDb(): ?DbConnection { return $this->vm->getConnection(); } - protected function assemble() + protected function assemble(): void { $vm = $this->vm; - /** @var \Icinga\Module\Vspheredb\Db $connection */ + /** @var Db $connection */ $connection = $vm->getConnection(); $lookup = new PathLookup($connection->getDbAdapter()); $hostUuid = $vm->get('runtime_host_uuid'); @@ -60,14 +61,12 @@ protected function assemble() $hostInfo = [ $lookup->linkToObject($hostUuid), Html::tag('br'), - ConnectionStateDetails::getFor($vm->get('connection_state')), + ConnectionStateDetails::getFor($vm->get('connection_state')) ]; $hostResources = $this->prepareHostInfo($host, $quickStats); - } catch (NotFoundError $e) { + } catch (NotFoundError) { $hostResources = '-'; - $hostInfo = Html::tag('span', [ - 'class' => 'error' - ], $this->translate('Failed to load related host')); + $hostInfo = Html::tag('span', ['class' => 'error'], $this->translate('Failed to load related host')); } } @@ -77,31 +76,29 @@ protected function assemble() $this->translate('Host Resources') => $hostResources, $this->translate('Resource Pool') => $lookup->linkToObject($vm->get('resource_pool_uuid')), $this->translate('Path') => PathToObjectRenderer::render($vm), - $this->translate('vCenter') => new VCenterLink($this->vCenter), + $this->translate('vCenter') => new VCenterLink($this->vCenter) ]); } - protected function prepareHostInfo(HostSystem $host, HostQuickStats $quickStats) + protected function prepareHostInfo(HostSystem $host, HostQuickStats $quickStats): HtmlElement { $cpuCapacity = $host->get('hardware_cpu_cores') * $host->get('hardware_cpu_mhz'); $cpuUsed = $quickStats->get('overall_cpu_usage'); $memCapacity = $host->get('hardware_memory_size_mb'); $memUsed = $quickStats->get('overall_memory_usage_mb'); - return Html::tag('div', [ - 'class' => 'resource-info-small' - ], Html::tag('div', [ + return Html::tag('div', ['class' => 'resource-info-small'], Html::tag('div', [ new CpuUsage($cpuUsed, $cpuCapacity), - \sprintf( + sprintf( $this->translate('Free CPU: %s'), Format::mhz($cpuCapacity - $cpuUsed) ), Html::tag('br'), new MemoryUsage($memUsed, $memCapacity), - \sprintf( + sprintf( $this->translate('Free Memory: %s'), Format::mBytes($memCapacity - $memUsed) - ), + ) ])); } } diff --git a/library/Vspheredb/Web/Table/Object/known-vendor-model-images.php b/library/Vspheredb/Web/Table/Object/known-vendor-model-images.php index 56d900bf..882b09bf 100644 --- a/library/Vspheredb/Web/Table/Object/known-vendor-model-images.php +++ b/library/Vspheredb/Web/Table/Object/known-vendor-model-images.php @@ -15,7 +15,7 @@ 'UCSC-C480-M5' => 'https://www.cisco.com/c/dam/en/us/products/collateral/servers-unified-computing/' . 'ucs-c-series-rack-servers/datasheet-c78-739291.docx/_jcr_content/renditions/datasheet-c78-739291_0.png', 'UCSC-C240-M6S' => 'https://www.cisco.com/content/dam/en/us/products/collateral/servers-unified-computing/' - . 'ucs-c-series-rack-servers/images/cisco-ucs-c240-m6-rack-server.png', + . 'ucs-c-series-rack-servers/images/cisco-ucs-c240-m6-rack-server.png' ], 'Dell Inc.' => [ 'PowerEdge R610' => 'https://i.dell.com/is/image/DellContent/content/dam/' @@ -57,7 +57,7 @@ . 'c6525/global_spi/ng/enterprise-server-poweredge-r7515-lf-bestof-500-ng.psd?fmt=png-alpha', 'PowerEdge R7525' => 'https://i.dell.com/is/image/DellContent/content/dam/' . 'global-site-design/product_images/dell_enterprise_products/enterprise_systems/poweredge/' - . 'poweredge_r7525/global_spi/ng/enterprise-servers-poweredge-r7525-lf-bestof-500-ng.psd?fmt=png-alpha', + . 'poweredge_r7525/global_spi/ng/enterprise-servers-poweredge-r7525-lf-bestof-500-ng.psd?fmt=png-alpha' ], 'HPE' => [ // End of life, found no HPE URL: @@ -69,19 +69,19 @@ 'ProLiant DL360 Gen10' => 'https://assets.ext.hpe.com/is/image/hpedam/s00005869?$zoom$#.png', 'ProLiant DL380 Gen10' => [ 'url' => 'https://assets.ext.hpe.com/is/image/hpedam/s00009709?$zoom$#.png', - 'class' => 'vendor-model-hpe-proliant-dl380-gen10', + 'class' => 'vendor-model-hpe-proliant-dl380-gen10' ], 'ProLiant DL380 Gen10 Plus' => [ - 'url' => 'https://assets.ext.hpe.com/is/image/hpedam/s00009868?$zoom$#.png', + 'url' => 'https://assets.ext.hpe.com/is/image/hpedam/s00009868?$zoom$#.png' ], 'ProLiant DL385 Gen10 Plus' => 'https://assets.ext.hpe.com/is/image/hpedam/s00009923?$zoom$#.png', 'ProLiant DL560 Gen10' => [ 'url' => 'https://assets.ext.hpe.com/is/image/hpedam/s00002844?$zoom$#.png', - 'class' => 'vendor-model-hpe-proliant-dl560-gen10', + 'class' => 'vendor-model-hpe-proliant-dl560-gen10' ], 'ProLiant DL580 Gen10' => [ 'url' => 'https://assets.ext.hpe.com/is/image/hpedam/s00005353?$zoom$#.png', - 'class' => 'vendor-model-hpe-proliant-dl580-gen10', + 'class' => 'vendor-model-hpe-proliant-dl580-gen10' ], 'Synergy 480 Gen10' => 'https://assets.ext.hpe.com/is/image/hpedam/s00002866?$zoom$#.png', @@ -96,7 +96,7 @@ // 'ProLiant DL580 Gen10' => 'https://assets.ext.hpe.com/is/image/hpedam/s00001910?$zoom$#.png', // Variant: - // 'ProLiant DL560 Gen10' => 'https://assets.ext.hpe.com/is/image/hpedam/s00004976?$zoom$#.png', + // 'ProLiant DL560 Gen10' => 'https://assets.ext.hpe.com/is/image/hpedam/s00004976?$zoom$#.png' ], 'HP' => [ 'ProLiant DL580 Gen9' => 'https://support.hpe.com/hpesc/public/api/document/c04683220/' @@ -106,7 +106,7 @@ 'ProLiant DL380 Gen9' => [ 'url' => 'https://techlibrary.hpe.com/docs/enterprise/servers/DL380Gen9/' . 'DL380Gen9-setup/system_setup_overview/222457.png', - 'class' => 'vendor-model-hp-proliant-dl380-gen9', + 'class' => 'vendor-model-hp-proliant-dl380-gen9' ], 'ProLiant BL460c Gen9' => 'https://techlibrary.hpe.com/docs/enterprise/servers/BL460cGen9/' . 'BL460cGen9-setup/de/system_setup_overview/189999.png' @@ -124,7 +124,7 @@ 'ThinkAgile HX7520 Appliance -[7X84CTO6WW]-' => 'https://lenovopress.lenovo.com/assets/images/LP0730/' . 'HX7520-overview.png', 'Lenovo ThinkAgile HX7520 Appliance -[7X84CTO6WW]-' => 'https://lenovopress.lenovo.com/assets/images/LP0730/' - . 'HX7520-overview.png', + . 'HX7520-overview.png' ], 'FUJITSU' => [ 'PRIMERGY CX2560 M5' => 'https://www.fujitsu.com/de/imagesgig5/W-DK43300_tcm20-4285182_tcm20-5309118-32.png', @@ -132,7 +132,7 @@ . '.png', 'PRIMERGY RX2540 M2' => 'https://www.fujitsu.com/de/Images/W-DK42852_tcm20-3057159.png', 'PRIMERGY RX2540 M3' => 'https://www.fujitsu.com/de/Images/W-DK42852_tcm20-3057159.png', - 'PRIMERGY RX2540 M4' => 'https://www.fujitsu.com/de/Images/W-DK42852_tcm20-3057159.png', + 'PRIMERGY RX2540 M4' => 'https://www.fujitsu.com/de/Images/W-DK42852_tcm20-3057159.png' ], 'IBM' => [ '/^(?:System )?x3850 X6/' => 'https://lenovopress.com/assets/images/tips1084/0.212C.jpg', @@ -146,6 +146,6 @@ ], 'Nutanix' => [ 'NX-3170-G8' => 'https://download.nutanix.com/documentation/NX-hardware/images/' - . 'front-panel-callouts-nx3170g8-nx8170g8.png', - ], + . 'front-panel-callouts-nx3170g8-nx8170g8.png' + ] ]; diff --git a/library/Vspheredb/Web/Table/Objects/ComputeClusterHostSummaryTable.php b/library/Vspheredb/Web/Table/Objects/ComputeClusterHostSummaryTable.php index 1435f91b..ab45be96 100644 --- a/library/Vspheredb/Web/Table/Objects/ComputeClusterHostSummaryTable.php +++ b/library/Vspheredb/Web/Table/Objects/ComputeClusterHostSummaryTable.php @@ -6,20 +6,20 @@ class ComputeClusterHostSummaryTable extends HostSummaryTable { - protected $baseUrl = 'vspheredb/compute-cluster'; + protected ?string $baseUrl = 'vspheredb/compute-cluster'; - protected $baseUrlHosts = 'vspheredb/compute-cluster/hosts'; + protected string $baseUrlHosts = 'vspheredb/compute-cluster/hosts'; - protected $groupBy = 'o.uuid'; + protected ?string $groupBy = 'o.uuid'; - protected $nameColumn = 'o.object_name'; + protected ?string $nameColumn = 'o.object_name'; - protected function getGroupingTitle() + protected function getGroupingTitle(): string { return $this->translate('Compute Cluster'); } - protected function getFilterParams($row) + protected function getFilterParams(object $row): array { return Util::uuidParams($row->uuid); } diff --git a/library/Vspheredb/Web/Table/Objects/DatacentersTable.php b/library/Vspheredb/Web/Table/Objects/DatacentersTable.php index f9ae94b2..c286371d 100644 --- a/library/Vspheredb/Web/Table/Objects/DatacentersTable.php +++ b/library/Vspheredb/Web/Table/Objects/DatacentersTable.php @@ -2,11 +2,14 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; +use gipfl\ZfDb\Select; +use Zend_Db_Select; + class DatacentersTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/vms?showDescendants'; + protected ?string $baseUrl = 'vspheredb/vms?showDescendants'; - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createOverallStatusColumn(), @@ -14,21 +17,18 @@ protected function initialize() ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'overall_status', - 'object_name', + 'object_name' ]; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->where('object_type = ?', 'Datacenter'); - - return $query; + return $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->where('object_type = ?', 'Datacenter'); } } diff --git a/library/Vspheredb/Web/Table/Objects/DatastoreTable.php b/library/Vspheredb/Web/Table/Objects/DatastoreTable.php index b9a28d96..cd587177 100644 --- a/library/Vspheredb/Web/Table/Objects/DatastoreTable.php +++ b/library/Vspheredb/Web/Table/Objects/DatastoreTable.php @@ -3,131 +3,116 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Data\Anonymizer; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\Web\Widget\DatastoreUsage; use Icinga\Util\Format; +use ipl\Html\Attributes; use Ramsey\Uuid\Uuid; +use Zend_Db_Select; -class DatastoreTable extends ObjectsTable +class DatastoreTable extends PercentObjectsTable { - protected function initialize() + protected function initialize(): void { - $this->addAttributes(['class' => 'datastores-table']); + $this->addAttributes(Attributes::create(['class' => 'datastores-table'])); $this->addAvailableColumns([ $this->createOverallStatusColumn(), + $this->createColumn('object_name', $this->translate('Name'), [ - 'overall_status' => 'o.overall_status', - 'object_name' => 'o.object_name', - 'uuid' => 'o.uuid', - 'capacity' => 'ds.capacity', - 'free_space' => 'ds.free_space', - 'uncommitted' => 'ds.uncommitted', - 'free_space_percent' => '(ds.free_space / ds.capacity) * 100', - 'uncommitted_percent' => '(ds.uncommitted / ds.capacity) * 100', - ])->setRenderer(function ($row) { - $row->object_name = Anonymizer::anonymizeString($row->object_name); - if (in_array('overall_status', $this->getChosenColumnNames())) { - $result = []; - } else { - $statusRenderer = $this->overallStatusRenderer(); - $result = [$statusRenderer($row)]; - } - $title = sprintf( + 'overall_status' => 'o.overall_status', + 'object_name' => 'o.object_name', + 'uuid' => 'o.uuid', + 'capacity' => 'ds.capacity', + 'free_space' => 'ds.free_space', + 'uncommitted' => 'ds.uncommitted', + 'free_space_percent' => '(ds.free_space / ds.capacity) * 100', + 'uncommitted_percent' => '(ds.uncommitted / ds.capacity) * 100' + ]) + ->setRenderer(function ($row) { + $row->object_name = Anonymizer::anonymizeString($row->object_name); + if (in_array('overall_status', $this->getChosenColumnNames())) { + $result = []; + } else { + $statusRenderer = $this->overallStatusRenderer(); + $result = [$statusRenderer($row)]; + } + $title = sprintf( // '%d VM(s), %s of %s used, %s uncommitted', - '%s of %s used, %s uncommitted', - // $row->cnt_vm, - $this->formatBytesPercent($row, 'free_space'), - Format::bytes($row->capacity, Format::STANDARD_IEC), - $this->formatBytesPercent($row, 'uncommitted') - ); - - $result[] = Link::create( - $row->object_name, - 'vspheredb/datastore', - ['uuid' => Uuid::fromBytes($row->uuid)->toString()], - ['title' => $title] - ); - - return $result; - }), + '%s of %s used, %s uncommitted', + // $row->cnt_vm, + $this->formatBytesPercent($row, 'free_space'), + Format::bytes($row->capacity, Format::STANDARD_IEC), + $this->formatBytesPercent($row, 'uncommitted') + ); + + $result[] = Link::create( + $row->object_name, + 'vspheredb/datastore', + ['uuid' => Uuid::fromBytes($row->uuid)->toString()], + ['title' => $title] + ); + + return $result; + }), + $this->createColumn('vcenter_name', $this->translate('vCenter / ESXi'), 'vc.name'), - $this->createColumn( - 'multiple_host_access', - $this->translate('Multiple Hosts'), - 'ds.multiple_host_access' - )->setRenderer(function ($row) { - return $row->multiple_host_access === 'y' ? $this->translate('Yes') : $this->translate('No'); - }), + + $this->createColumn('multiple_host_access', $this->translate('Multiple Hosts'), 'ds.multiple_host_access') + ->setRenderer( + fn($row) => $row->multiple_host_access === 'y' ? $this->translate('Yes') : $this->translate('No') + ), + $this->createColumn('free_space', $this->translate('Free'), 'ds.free_space') - ->setRenderer(function ($row) { - return Format::bytes($row->free_space, Format::STANDARD_IEC); - }), + ->setRenderer(fn($row) => Format::bytes($row->free_space, Format::STANDARD_IEC)), + $this->createColumn('free_space_percent', $this->translate('Free (%)'), [ - 'free_space_percent' => '(ds.free_space / ds.capacity) * 100' - ])->setRenderer(function ($row) { - return $this->formatPercent($row->free_space_percent); - }), + 'free_space_percent' => '(ds.free_space / ds.capacity) * 100' + ]) + ->setRenderer(fn($row) => $this->formatPercent($row->free_space_percent)), + $this->createColumn('uncommitted', $this->translate('Uncommitted'), 'ds.uncommitted') - ->setRenderer(function ($row) { - return Format::bytes($row->uncommitted, Format::STANDARD_IEC); - }), + ->setRenderer(fn($row) => Format::bytes($row->uncommitted, Format::STANDARD_IEC)), + $this->createColumn('uncommitted_percent', $this->translate('Uncommitted (%)'), [ - 'uncommitted_percent' => '(ds.uncommitted / ds.capacity) * 100' - ])->setRenderer(function ($row) { - return $this->formatPercent($row->uncommitted_percent); - }), + 'uncommitted_percent' => '(ds.uncommitted / ds.capacity) * 100' + ]) + ->setRenderer(fn($row) => $this->formatPercent($row->uncommitted_percent)), + $this->createColumn('size', $this->translate('Size'), 'ds.capacity') + ->setRenderer(fn($row) => Format::bytes($row->capacity, Format::STANDARD_IEC)), + + $this->createColumn('cnt_vms', $this->translate('VMs'), ['cnt_vms' => 'COALESCE(vdu.cnt_vms, 0)']) + ->setDefaultSortDirection('DESC'), + + $this->createColumn('usage', $this->translate('Usage'), ['uuid' => 'o.uuid']) ->setRenderer(function ($row) { - return Format::bytes($row->capacity, Format::STANDARD_IEC); - }), - $this->createColumn('cnt_vms', $this->translate('VMs'), [ - 'cnt_vms' => 'COALESCE(vdu.cnt_vms, 0)', - ])->setDefaultSortDirection('DESC'), - $this->createColumn('usage', $this->translate('Usage'), [ - 'uuid' => 'o.uuid' - ])->setRenderer(function ($row) { - /** @var Db $connection */ - $connection = $this->connection(); - $usage = new DatastoreUsage(Datastore::load($row->uuid, $connection)); - $usage->getAttributes()->add('class', 'compact'); - $usage->loadAllVmDisks()->addFreeDatastoreSpace(); - - return $usage; - })->setSortExpression( - '1 - (ds.free_space / ds.capacity)' - )->setDefaultSortDirection('DESC'), + /** @var Db $connection */ + $connection = $this->connection(); + $usage = new DatastoreUsage(Datastore::load($row->uuid, $connection)); + $usage->getAttributes()->add('class', 'compact'); + $usage->loadAllVmDisks()->addFreeDatastoreSpace(); + + return $usage; + }) + ->setSortExpression('1 - (ds.free_space / ds.capacity)') + ->setDefaultSortDirection('DESC') ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'object_name', 'free_space', 'size', - 'usage', + 'usage' ]; } - protected function formatBytesPercent($row, $name) - { - $bytes = $row->$name; - $percent = $row->{"{$name}_percent"}; - return sprintf( - '%s (%s)', - Format::bytes($bytes, Format::STANDARD_IEC), - $this->formatPercent($percent) - ); - } - - protected function formatPercent($value) - { - return sprintf('%0.2f%%', $value); - } - - public function sortBy($columns) + public function sortBy(array|string $columns): static { parent::sortBy($columns); @@ -136,7 +121,7 @@ public function sortBy($columns) return $this; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { $wantsVCenter = false; $columns = $this->getRequiredDbColumns(); @@ -146,34 +131,19 @@ public function prepareQuery() ->group('o.uuid'); foreach ($columns as $column) { - if (substr($column, 0, 3) === 'vc.') { + if (str_starts_with($column, 'vc.')) { $wantsVCenter = true; } } if ($this->hasColumn('cnt_vms')) { - $vduQuery = $this->db()->select()->from('vm_datastore_usage', [ - 'cnt_vms' => 'COUNT(*)', - 'ds_uuid' => 'datastore_uuid', - ])->group('datastore_uuid'); - $query->joinLeft( - ['vdu' => $vduQuery], - 'vdu.ds_uuid = o.uuid', - [] - ); + $vduQuery = $this->db()->select() + ->from('vm_datastore_usage', ['cnt_vms' => 'COUNT(*)', 'ds_uuid' => 'datastore_uuid']) + ->group('datastore_uuid'); + $query->joinLeft(['vdu' => $vduQuery], 'vdu.ds_uuid = o.uuid', []); } if ($wantsVCenter) { - $query->join( - ['vc' => 'vcenter'], - 'vc.instance_uuid = ds.vcenter_uuid', - [] - ); - } - if ($this->parentUuids) { - $query->where('o.parent_uuid IN (?)', $this->parentUuids); - } - if ($this->filterVCenter) { - $query->where('o.vcenter_uuid = ?', $this->filterVCenter->getUuid()); + $query->join(['vc' => 'vcenter'], 'vc.instance_uuid = ds.vcenter_uuid', []); } return $query; diff --git a/library/Vspheredb/Web/Table/Objects/GroupedvmsTable.php b/library/Vspheredb/Web/Table/Objects/GroupedvmsTable.php index e8b2c524..c2bd4688 100644 --- a/library/Vspheredb/Web/Table/Objects/GroupedvmsTable.php +++ b/library/Vspheredb/Web/Table/Objects/GroupedvmsTable.php @@ -3,62 +3,40 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; +use Icinga\Module\Vspheredb\Format; use Icinga\Module\Vspheredb\Util; +use Icinga\Module\Vspheredb\Web\Table\SimpleColumn; use Icinga\Module\Vspheredb\Web\Widget\MemoryUsage; -use Icinga\Module\Vspheredb\Format; +use Zend_Db_Select; class GroupedvmsTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/vm'; + protected ?string $baseUrl = 'vspheredb/vm'; - protected $groupByAlias = 'project'; + protected string $groupByAlias = 'project'; - protected $groupBy = '(SUBSTR(o.object_name, 1, POSITION(\'-\' IN o.object_name) - 1))'; + protected string $groupBy = '(SUBSTR(o.object_name, 1, POSITION(\'-\' IN o.object_name) - 1))'; - public function filter($uuid) + public function filter(string $uuid): static { $this->getQuery()->where('vm.runtime_host_uuid = ?', $uuid); return $this; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->join( - ['vm' => 'virtual_machine'], - 'o.uuid = vm.uuid', - [] - )->group($this->groupByAlias); - - $query->join( - ['h' => 'host_system'], - 'vm.runtime_host_uuid = h.uuid', - [] - )->join( - ['ho' => 'object'], - 'ho.uuid = h.uuid', - [] - ); - $query->join( - ['vqs' => 'vm_quick_stats'], - 'vqs.uuid = vm.uuid', - [] - ); - - if ($this->parentUuids) { - $query->where('ho.parent_uuid IN (?)', $this->parentUuids); - } - if ($this->filterVCenter) { - $query->where('ho.vcenter_uuid = ?', $this->filterVCenter->getUuid()); - } - - return $query; + return $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []) + ->group($this->groupByAlias) + ->join(['h' => 'host_system'], 'vm.runtime_host_uuid = h.uuid', []) + ->join(['ho' => 'object'], 'ho.uuid = h.uuid', []) + ->join(['vqs' => 'vm_quick_stats'], 'vqs.uuid = vm.uuid', []); } - protected function createGroupingColumn() + protected function createGroupingColumn(): SimpleColumn { return $this->createColumn($this->groupByAlias, 'Project', $this->groupBy) ->setRenderer(function ($row) { @@ -76,49 +54,48 @@ protected function createGroupingColumn() }); } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createGroupingColumn(), /* $this->createColumn('cpu', 'CPU', [ 'used_mhz' => 'SUM(vqs.overall_cpu_usage)', - 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)', + 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)' ])->setRenderer(function ($row) { return new CpuUsage($row->used_mhz, $row->total_mhz); })->setSortExpression( 'SUM(hqs.overall_cpu_usage) / SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)' )->setDefaultSortDirection('DESC'), */ + $this->createColumn('hardware_numcpu', $this->translate('vCPU Count'), 'SUM(vm.hardware_numcpu)') ->setDefaultSortDirection('DESC'), + $this->createColumn('cpu_usage', 'CPU', 'SUM(vqs.overall_cpu_usage)') - ->setRenderer(function ($row) { - return Format::mhz($row->cpu_usage); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mhz($row->cpu_usage)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('memory', $this->translate('Memory'), [ 'used_mb' => 'SUM(vqs.guest_memory_usage_mb)', 'total_mb' => 'SUM(vm.hardware_memorymb)', - 'host_used_mb' => 'SUM(vqs.host_memory_usage_mb)', - ])->setRenderer(function ($row) { - return new MemoryUsage($row->used_mb, $row->total_mb, $row->host_used_mb); - })->setSortExpression( - 'SUM(vqs.guest_memory_usage_mb) / SUM(vm.hardware_memorymb)' - )->setDefaultSortDirection('DESC'), + 'host_used_mb' => 'SUM(vqs.host_memory_usage_mb)' + ]) + ->setRenderer(fn($row) => new MemoryUsage($row->used_mb, $row->total_mb, $row->host_used_mb)) + ->setSortExpression('SUM(vqs.guest_memory_usage_mb) / SUM(vm.hardware_memorymb)') + ->setDefaultSortDirection('DESC'), $this->createColumn('host_memory', $this->translate('Host Memory'), [ - 'host_used_mb' => 'SUM(vqs.host_memory_usage_mb)', - 'total_mb' => 'SUM(vm.hardware_memorymb)', - ])->setRenderer(function ($row) { - return new MemoryUsage($row->host_used_mb, $row->total_mb); - })->setSortExpression( - 'AVG(vqs.host_memory_usage_mb / vm.hardware_memorymb)' - )->setDefaultSortDirection('DESC'), - + 'host_used_mb' => 'SUM(vqs.host_memory_usage_mb)', + 'total_mb' => 'SUM(vm.hardware_memorymb)' + ]) + ->setRenderer(fn($row) => new MemoryUsage($row->host_used_mb, $row->total_mb)) + ->setSortExpression('AVG(vqs.host_memory_usage_mb / vm.hardware_memorymb)') + ->setDefaultSortDirection('DESC'), /* $this->createColumn('memory', 'Host Memory', [ 'used_mb' => 'SUM(vqs.host_memory_usage_mb)', - 'total_mb' => 'SUM(vm.hardware_memorymb)', + 'total_mb' => 'SUM(vm.hardware_memorymb)' ])->setRenderer(function ($row) { $used = $row->used_mb * 1024 * 1024; $total = $row->total_mb * 1024 * 1024; @@ -131,24 +108,23 @@ protected function initialize() return [ new SimpleUsageBar($used, $total, $title), Html::tag('small', ['style' => 'float: left'], 'Used: ' . Format::bytes($used)), - Html::tag('small', ['style' => 'float: right'], 'Capacity: ' . Format::bytes($total)), + Html::tag('small', ['style' => 'float: right'], 'Capacity: ' . Format::bytes($total)) ]; })->setSortExpression( 'AVG(hqs.overall_memory_usage_mb / h.hardware_memory_size_mb)' )->setDefaultSortDirection('DESC'), -*/ + */ $this->createColumn('vms', 'VMs', 'COUNT(*)') ->setDefaultSortDirection('DESC'), - $this->createColumn('hardware_memorymb', 'Memory Capacity', 'SUM(vm.hardware_memorymb)') - ->setRenderer(function ($row) { - return Format::mBytes($row->hardware_memorymb); - })->setDefaultSortDirection('DESC'), + $this->createColumn('hardware_memorymb', 'Memory Capacity', 'SUM(vm.hardware_memorymb)') + ->setRenderer(fn($row) => Format::mBytes($row->hardware_memorymb)) + ->setDefaultSortDirection('DESC') ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'project', diff --git a/library/Vspheredb/Web/Table/Objects/HostSummaryTable.php b/library/Vspheredb/Web/Table/Objects/HostSummaryTable.php index d2c9f4cc..c33347e5 100644 --- a/library/Vspheredb/Web/Table/Objects/HostSummaryTable.php +++ b/library/Vspheredb/Web/Table/Objects/HostSummaryTable.php @@ -3,61 +3,46 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Format; +use Icinga\Module\Vspheredb\Web\Table\SimpleColumn; use Icinga\Module\Vspheredb\Web\Widget\CpuUsage; use Icinga\Module\Vspheredb\Web\Widget\MemoryUsage; use ipl\Html\Html; use Ramsey\Uuid\Uuid; +use Zend_Db_Select; abstract class HostSummaryTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/computeresource'; + protected ?string $baseUrl = 'vspheredb/computeresource'; - protected $baseUrlHosts = 'vspheredb/hosts'; + protected string $baseUrlHosts = 'vspheredb/hosts'; - protected $searchColumns = [ - 'name', - ]; + protected $searchColumns = ['name']; - protected $groupByAlias = 'name'; + protected string $groupByAlias = 'name'; - protected $nameColumn; + protected ?string $nameColumn = null; - protected $groupBy; + protected ?string $groupBy = null; - abstract protected function getFilterParams($row); + abstract protected function getFilterParams(object $row): array; - abstract protected function getGroupingTitle(); + abstract protected function getGroupingTitle(): string; - protected function prepareUnGroupedQuery() + protected function prepareUnGroupedQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->join( - ['ho' => 'object'], - 'ho.parent_uuid = o.uuid', - [] - )->join( - ['h' => 'host_system'], - 'ho.uuid = h.uuid', - [] - )->join( - ['hqs' => 'host_quick_stats'], - 'hqs.uuid = h.uuid', - [] - )->where('h.runtime_power_state = ?', 'poweredOn'); + return $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['ho' => 'object'], 'ho.parent_uuid = o.uuid', []) + ->join(['h' => 'host_system'], 'ho.uuid = h.uuid', []) + ->join(['hqs' => 'host_quick_stats'], 'hqs.uuid = h.uuid', []) + ->where('h.runtime_power_state = ?', 'poweredOn'); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { $query = $this->prepareUnGroupedQuery(); - if ($this->parentUuids) { - $query->where('o.uuid IN (?)', $this->parentUuids); - } - if ($this->filterVCenter) { - $query->where('o.vcenter_uuid = ?', $this->filterVCenter->getUuid()); - } if ($this->groupBy !== null) { $query->group($this->groupBy); @@ -66,11 +51,11 @@ public function prepareQuery() return $query; } - protected function createGroupingColumn() + protected function createGroupingColumn(): SimpleColumn { return $this->createColumn($this->groupByAlias, $this->getGroupingTitle(), [ 'name' => $this->nameColumn, - 'uuid' => $this->groupBy, + 'uuid' => $this->groupBy ] + $this->getHostCountColumns())->setRenderer(function ($row) { $link = Link::create( $row->{$this->groupByAlias}, @@ -82,106 +67,109 @@ protected function createGroupingColumn() return [ $this->getExtraIcons($row), $link, - $this->renderHostSummaries($row), + $this->renderHostSummaries($row) ]; }); } - protected function getExtraIcons($row) + protected function getExtraIcons(object $row) { } - protected function hasChosenColumn($name) + protected function hasChosenColumn(string $name): bool { return in_array($name, $this->getChosenColumnNames()); } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createGroupingColumn(), + $this->createColumn('cnt_hosts', $this->translate('Hosts'), 'COUNT(*)') - ->setRenderer(function ($row) { - return Html::tag('td', ['class' => 'text-right'], $row->cnt_hosts); - }) + ->setRenderer(fn($row) => Html::tag('td', ['class' => 'text-right'], $row->cnt_hosts)) ->setDefaultSortDirection('DESC'), - $this->createColumn( - 'hosts_status', - $this->translate('Hosts Status'), - $this->getHostCountColumns() - )->setRenderer(function ($row) { - $result = []; - $uuid = Uuid::fromBytes($row->uuid)->toString(); - foreach (['green', 'gray', 'yellow', 'red'] as $state) { - $column = "hosts_cnt_overall_$state"; - if ($row->$column > 0) { - $result[] = Link::create($row->$column, $this->baseUrlHosts, [ - 'vcenter' => $uuid, - 'overall_status' => $state - ], ['class' => ['state', $state]]); + + $this->createColumn('hosts_status', $this->translate('Hosts Status'), $this->getHostCountColumns()) + ->setRenderer(function ($row) { + $result = []; + $uuid = Uuid::fromBytes($row->uuid)->toString(); + foreach (['green', 'gray', 'yellow', 'red'] as $state) { + $column = "hosts_cnt_overall_$state"; + if ($row->$column > 0) { + $result[] = Link::create($row->$column, $this->baseUrlHosts, [ + 'vcenter' => $uuid, + 'overall_status' => $state + ], ['class' => ['state', $state]]); + } + } + + if (empty($result)) { + return '-'; } - } - if (empty($result)) { - return '-'; - } else { return $result; - } - })->setSortExpression([ - "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)", - "SUM(CASE WHEN ho.overall_status = 'yellow' THEN 1 ELSE 0 END)", - "SUM(CASE WHEN ho.overall_status = 'gray' THEN 1 ELSE 0 END)", - "SUM(CASE WHEN ho.overall_status = 'green' THEN 1 ELSE 0 END)", - ])->setDefaultSortDirection('DESC'), + }) + ->setSortExpression([ + "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)", + "SUM(CASE WHEN ho.overall_status = 'yellow' THEN 1 ELSE 0 END)", + "SUM(CASE WHEN ho.overall_status = 'gray' THEN 1 ELSE 0 END)", + "SUM(CASE WHEN ho.overall_status = 'green' THEN 1 ELSE 0 END)" + ]) + ->setDefaultSortDirection('DESC'), + $this->createColumn('cpu', $this->translate('CPU'), [ 'used_mhz' => 'SUM(hqs.overall_cpu_usage)', - 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)', - ])->setRenderer(function ($row) { - $bar = new CpuUsage($row->used_mhz, $row->total_mhz); - if ($this->hasChosenColumn('overall_cpu_usage') || $this->hasChosenColumn('hardware_cpu_mhz')) { - $bar->showLabels(false); - } - return $bar; - })->setSortExpression( - 'SUM(hqs.overall_cpu_usage) / SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)' - )->setDefaultSortDirection('DESC'), - $this->createColumn('overall_cpu_usage', $this->translate('Used'), 'SUM(hqs.overall_cpu_usage)') + 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)' + ]) ->setRenderer(function ($row) { - return Format::mhz($row->overall_cpu_usage); - })->setDefaultSortDirection('DESC'), + $bar = new CpuUsage($row->used_mhz, $row->total_mhz); + if ($this->hasChosenColumn('overall_cpu_usage') || $this->hasChosenColumn('hardware_cpu_mhz')) { + $bar->showLabels(false); + } + + return $bar; + }) + ->setSortExpression('SUM(hqs.overall_cpu_usage) / SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)') + ->setDefaultSortDirection('DESC'), + + $this->createColumn('overall_cpu_usage', $this->translate('Used'), 'SUM(hqs.overall_cpu_usage)') + ->setRenderer(fn($row) => Format::mhz($row->overall_cpu_usage)) + ->setDefaultSortDirection('DESC'), + $this->createColumn( 'hardware_cpu_mhz', $this->translate('Capacity'), 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)' - )->setRenderer(function ($row) { - return Format::mhz($row->hardware_cpu_mhz); - })->setDefaultSortDirection('DESC'), + ) + ->setRenderer(fn($row) => Format::mhz($row->hardware_cpu_mhz)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('hardware_cpu_cores', $this->translate('Cores'), 'SUM(h.hardware_cpu_cores)') - ->setRenderer(function ($row) { - return Html::tag('td', ['class' => 'text-right'], $row->hardware_cpu_cores); - }) + ->setRenderer(fn($row) => Html::tag('td', ['class' => 'text-right'], $row->hardware_cpu_cores)) ->setDefaultSortDirection('DESC'), $this->createColumn('memory', $this->translate('Memory'), [ 'used_mb' => 'SUM(hqs.overall_memory_usage_mb)', - 'total_mb' => 'SUM(h.hardware_memory_size_mb)', - ])->setRenderer(function ($row) { - $bar = new MemoryUsage($row->used_mb, $row->total_mb); - if ($this->hasChosenColumn('overall_memory_usage') || $this->hasChosenColumn('hardware_memorymb')) { - $bar->showLabels(false); - } - return $bar; - })->setSortExpression( - 'AVG(hqs.overall_memory_usage_mb / h.hardware_memory_size_mb)' - )->setDefaultSortDirection('DESC'), - $this->createColumn('overall_memory_usage', $this->translate('Used'), 'SUM(hqs.overall_memory_usage_mb)') + 'total_mb' => 'SUM(h.hardware_memory_size_mb)' + ]) ->setRenderer(function ($row) { - return Format::mBytes($row->overall_memory_usage); - })->setDefaultSortDirection('DESC'), + $bar = new MemoryUsage($row->used_mb, $row->total_mb); + if ($this->hasChosenColumn('overall_memory_usage') || $this->hasChosenColumn('hardware_memorymb')) { + $bar->showLabels(false); + } + return $bar; + }) + ->setSortExpression('AVG(hqs.overall_memory_usage_mb / h.hardware_memory_size_mb)') + ->setDefaultSortDirection('DESC'), + + $this->createColumn('overall_memory_usage', $this->translate('Used'), 'SUM(hqs.overall_memory_usage_mb)') + ->setRenderer(fn($row) => Format::mBytes($row->overall_memory_usage)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('hardware_memorymb', $this->translate('Capacity'), 'SUM(h.hardware_memory_size_mb)') - ->setRenderer(function ($row) { - return Format::mBytes($row->hardware_memorymb); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mBytes($row->hardware_memorymb)) + ->setDefaultSortDirection('DESC') /* // Not yet, this was an early prototype based no monitoring vars @@ -198,18 +186,18 @@ protected function initialize() ]); } - protected function getHostCountColumns() + protected function getHostCountColumns(): array { return [ - 'hosts_cnt' => 'COUNT(*)', + 'hosts_cnt' => 'COUNT(*)', 'hosts_cnt_overall_gray' => "SUM(CASE WHEN ho.overall_status = 'gray' THEN 1 ELSE 0 END)", 'hosts_cnt_overall_green' => "SUM(CASE WHEN ho.overall_status = 'green' THEN 1 ELSE 0 END)", 'hosts_cnt_overall_yellow' => "SUM(CASE WHEN ho.overall_status = 'yellow' THEN 1 ELSE 0 END)", - 'hosts_cnt_overall_red' => "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)", + 'hosts_cnt_overall_red' => "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)" ]; } - protected function renderHostSummaries($row) + protected function renderHostSummaries(object $row): ?array { $params = $this->getFilterParams($row); @@ -231,9 +219,12 @@ protected function renderHostSummaries($row) foreach (['red', 'yellow', 'gray', 'green'] as $state) { $column = "hosts_cnt_overall_$state"; if ($row->$column > 0) { - $result[] = Link::create($row->$column, 'vspheredb/hosts', $params + [ - 'overall_status' => $state - ], ['class' => ['state', $state]]); + $result[] = Link::create( + $row->$column, + 'vspheredb/hosts', + $params + ['overall_status' => $state], + ['class' => ['state', $state]] + ); } } } @@ -241,13 +232,14 @@ protected function renderHostSummaries($row) if (empty($result)) { return null; } + return [ Html::tag('br'), - Html::tag('small', $result), + Html::tag('small', $result) ]; } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ $this->groupByAlias, diff --git a/library/Vspheredb/Web/Table/Objects/HostsTable.php b/library/Vspheredb/Web/Table/Objects/HostsTable.php index 67451aac..0d54a5df 100644 --- a/library/Vspheredb/Web/Table/Objects/HostsTable.php +++ b/library/Vspheredb/Web/Table/Objects/HostsTable.php @@ -3,156 +3,164 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\DbObject\HostSystem; +use Icinga\Module\Vspheredb\Format; use Icinga\Module\Vspheredb\Util; use Icinga\Module\Vspheredb\Web\Widget\BiosInfo; use Icinga\Module\Vspheredb\Web\Widget\CpuUsage; use Icinga\Module\Vspheredb\Web\Widget\MemoryUsage; use Icinga\Module\Vspheredb\Web\Widget\PowerStateRenderer; use Icinga\Module\Vspheredb\Web\Widget\ServiceTagRenderer; -use Icinga\Module\Vspheredb\Format; +use Zend_Db_Select; class HostsTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/host'; + protected ?string $baseUrl = 'vspheredb/host'; - protected function initialize() + protected function initialize(): void { $serviceTagRenderer = new ServiceTagRenderer(); $powerStateRenderer = new PowerStateRenderer(); $this->addAvailableColumns([ $this->createOverallStatusColumn(), + $this->createColumn('runtime_power_state', $this->translate('Power'), 'h.runtime_power_state') ->setRenderer($powerStateRenderer), + $this->createObjectNameColumn(), + $this->createColumn('sysinfo_vendor', $this->translate('Vendor'), 'h.sysinfo_vendor'), + $this->createColumn('sysinfo_model', $this->translate('Model'), 'h.sysinfo_model'), + $this->createColumn('vcenter_name', $this->translate('vCenter / ESXi'), 'vc.name'), + $this->createColumn('bios_version', $this->translate('BIOS Version'), 'h.bios_version'), + $this->createColumn('bios_release_date', $this->translate('BIOS Release Date'), 'h.bios_release_date') - ->setRenderer(function ($row) { - return DateFormatter::formatDate(strtotime($row->bios_release_date)); - }), + ->setRenderer(fn($row) => DateFormatter::formatDate(strtotime($row->bios_release_date))), + $this->createColumn('service_tag', $this->translate('Service Tag'), [ 'service_tag' => 'h.service_tag', - 'sysinfo_vendor' => 'h.sysinfo_vendor', - ])->setRenderer($serviceTagRenderer), + 'sysinfo_vendor' => 'h.sysinfo_vendor' + ]) + ->setRenderer($serviceTagRenderer), + $this->createColumn('product_api_version', $this->translate('API Version'), [ - 'product_api_version' => 'h.product_api_version', + 'product_api_version' => 'h.product_api_version' ]), + $this->createColumn('cpu_usage', $this->translate('CPU Usage'), [ 'cpu_usage' => 'hqs.overall_cpu_usage', - 'cpu_total' => '(hardware_cpu_cores * hardware_cpu_mhz)', - ])->setRenderer(function ($row) { - return new CpuUsage($row->cpu_usage, $row->cpu_total); - })->setSortExpression( - 'hqs.overall_cpu_usage / (h.hardware_cpu_cores * h.hardware_cpu_mhz)' - )->setDefaultSortDirection('DESC'), + 'cpu_total' => '(hardware_cpu_cores * hardware_cpu_mhz)' + ]) + ->setRenderer(fn($row) => new CpuUsage($row->cpu_usage, $row->cpu_total)) + ->setSortExpression('hqs.overall_cpu_usage / (h.hardware_cpu_cores * h.hardware_cpu_mhz)') + ->setDefaultSortDirection('DESC'), + $this->createColumn('memory_usage', $this->translate('Memory Usage'), [ 'hardware_memory_size_mb' => 'h.hardware_memory_size_mb', - 'memory_usage_mb' => 'hqs.overall_memory_usage_mb', - ])->setRenderer(function ($row) { - return new MemoryUsage($row->memory_usage_mb, $row->hardware_memory_size_mb); - })->setSortExpression( - '(hqs.overall_memory_usage_mb / h.hardware_memory_size_mb)' - )->setDefaultSortDirection('DESC'), + 'memory_usage_mb' => 'hqs.overall_memory_usage_mb' + ]) + ->setRenderer(fn($row) => new MemoryUsage($row->memory_usage_mb, $row->hardware_memory_size_mb)) + ->setSortExpression('(hqs.overall_memory_usage_mb / h.hardware_memory_size_mb)') + ->setDefaultSortDirection('DESC'), + $this->createColumn('hardware_cpu_cores', $this->translate('CPU Cores'), 'h.hardware_cpu_cores') ->setDefaultSortDirection('DESC'), + $this->createColumn('vms_overall_status', $this->translate('VM Status'), [ 'vms_cnt_overall_gray' => 'vms.vms_cnt_overall_gray', 'vms_cnt_overall_green' => 'vms.vms_cnt_overall_green', 'vms_cnt_overall_yellow' => 'vms.vms_cnt_overall_yellow', - 'vms_cnt_overall_red' => 'vms.vms_cnt_overall_red', - ])->setRenderer(function ($row) { - $result = []; - foreach (['red', 'yellow', 'gray', 'green'] as $state) { - $column = "vms_cnt_overall_$state"; - if ($row->$column > 0) { - $result[] = Link::create( - $row->$column, - 'vspheredb/host/vms', - [ - 'uuid' => Util::niceUuid($row->uuid), - 'overall_status' => $state - ], - ['class' => ['state', $state]] - ); + 'vms_cnt_overall_red' => 'vms.vms_cnt_overall_red' + ]) + ->setRenderer(function ($row) { + $result = []; + foreach (['red', 'yellow', 'gray', 'green'] as $state) { + $column = "vms_cnt_overall_$state"; + if ($row->$column > 0) { + $result[] = Link::create( + $row->$column, + 'vspheredb/host/vms', + [ + 'uuid' => Util::niceUuid($row->uuid), + 'overall_status' => $state + ], + ['class' => ['state', $state]] + ); + } + } + + if (empty($result)) { + return '-'; } - } - if (empty($result)) { - return '-'; - } else { return $result; - } - })->setSortExpression([ - 'vms.vms_cnt_overall_red', - 'vms.vms_cnt_overall_yellow', - 'vms.vms_cnt_overall_gray', - 'vms.vms_cnt_overall_green', - ])->setDefaultSortDirection('DESC'), + }) + ->setSortExpression([ + 'vms.vms_cnt_overall_red', + 'vms.vms_cnt_overall_yellow', + 'vms.vms_cnt_overall_gray', + 'vms.vms_cnt_overall_green' + ]) + ->setDefaultSortDirection('DESC'), + $this->createColumn('vms_cnt_cpu', $this->translate('VM CPUs'), 'vms.cnt_cpu') ->setDefaultSortDirection('DESC'), + $this->createColumn( 'pcpu_vcpu_ration', $this->translate('vCPU/pCPU'), '(vms.cnt_cpu / h.hardware_cpu_cores)' - )->setRenderer(function ($row) { - return sprintf('%.3g:1', $row->pcpu_vcpu_ration); - })->setDefaultSortDirection('DESC'), + ) + ->setRenderer(fn($row) => sprintf('%.3g:1', $row->pcpu_vcpu_ration)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('hardware_memory_size_mb', $this->translate('Memory'), 'h.hardware_memory_size_mb') - ->setRenderer(function ($row) { - return Format::mBytes($row->hardware_memory_size_mb); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mBytes($row->hardware_memory_size_mb)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('vms_memorymb', $this->translate('VMs Memory'), 'vms.memorymb') - ->setRenderer(function ($row) { - return Format::mBytes($row->vms_memorymb); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mBytes($row->vms_memorymb)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('vms_cnt', $this->translate('VMs'), 'vms.cnt') ->setDefaultSortDirection('DESC'), + $this->createColumn('spectre_meltdown', $this->translate('Spectre / Meltdown'), [ 'sysinfo_vendor' => 'h.sysinfo_vendor', 'sysinfo_model' => 'h.sysinfo_model', 'bios_version' => 'h.bios_version', - 'bios_release_date' => 'h.bios_release_date', - ])->setRenderer(function ($row) { - $host = HostSystem::create([ + 'bios_release_date' => 'h.bios_release_date' + ]) + ->setRenderer(fn($row) => new BiosInfo(HostSystem::create([ 'sysinfo_vendor' => $row->sysinfo_vendor, 'sysinfo_model' => $row->sysinfo_model, 'bios_version' => $row->bios_version, - 'bios_release_date' => $row->bios_release_date, - ]); - - return new BiosInfo($host); - }), - $this->createColumn('uptime', $this->translate('Uptime'), [ - 'uptime' => 'hqs.uptime', - ])->setRenderer(function ($row) { - if ($row->uptime === null) { - return null; - } - - return DateFormatter::formatDuration($row->uptime); - }), + 'bios_release_date' => $row->bios_release_date + ]))), + $this->createColumn('uptime', $this->translate('Uptime'), ['uptime' => 'hqs.uptime']) + ->setRenderer(fn($row) => $row->uptime === null ? null : DateFormatter::formatDuration($row->uptime)) ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'object_name', 'cpu_usage', - 'memory_usage', + 'memory_usage' ]; } - protected function createVmSubQuery() + protected function createVmSubQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - ['vc' => 'virtual_machine'], - [ + return $this->db()->select() + ->from(['vc' => 'virtual_machine'], [ 'cnt' => 'COUNT(*)', 'cnt_cpu' => 'SUM(vc.hardware_numcpu)', 'memorymb' => 'SUM(vc.hardware_memorymb)', @@ -160,56 +168,37 @@ protected function createVmSubQuery() 'vms_cnt_overall_gray' => "SUM(CASE WHEN vo.overall_status = 'gray' THEN 1 ELSE 0 END)", 'vms_cnt_overall_green' => "SUM(CASE WHEN vo.overall_status = 'green' THEN 1 ELSE 0 END)", 'vms_cnt_overall_yellow' => "SUM(CASE WHEN vo.overall_status = 'yellow' THEN 1 ELSE 0 END)", - 'vms_cnt_overall_red' => "SUM(CASE WHEN vo.overall_status = 'red' THEN 1 ELSE 0 END)", - ] - )->join( - ['vo' => 'object'], - 'vo.uuid = vc.uuid', - [] - )->group('vc.runtime_host_uuid'); + 'vms_cnt_overall_red' => "SUM(CASE WHEN vo.overall_status = 'red' THEN 1 ELSE 0 END)" + ]) + ->join(['vo' => 'object'], 'vo.uuid = vc.uuid', []) + ->group('vc.runtime_host_uuid'); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { $columns = $this->getRequiredDbColumns(); $wantsVms = false; $wantsVCenter = false; foreach ($columns as $column) { - if (preg_match('/^\(?vms\./', $column)) { + if (str_starts_with($column, 'vms.') || str_starts_with($column, '(vms.')) { $wantsVms = true; break; } - if (substr($column, 0, 3) === 'vc.') { + if (str_starts_with($column, 'vc.')) { $wantsVCenter = true; } } - $query = $this->db()->select()->from( - ['o' => 'object'], - $columns - )->join( - ['h' => 'host_system'], - 'o.uuid = h.uuid', - [] - )->joinLeft( - ['hqs' => 'host_quick_stats'], - 'h.uuid = hqs.uuid', - [] - ); + $query = $this->db()->select() + ->from(['o' => 'object'], $columns) + ->join(['h' => 'host_system'], 'o.uuid = h.uuid', []) + ->joinLeft(['hqs' => 'host_quick_stats'], 'h.uuid = hqs.uuid', []); if ($wantsVms) { - $query->joinLeft( - ['vms' => $this->createVmSubQuery()], - 'vms.runtime_host_uuid = h.uuid', - [] - ); + $query->joinLeft(['vms' => $this->createVmSubQuery()], 'vms.runtime_host_uuid = h.uuid', []); } if ($wantsVCenter) { - $query->join( - ['vc' => 'vcenter'], - 'vc.instance_uuid = h.vcenter_uuid', - [] - ); + $query->join(['vc' => 'vcenter'], 'vc.instance_uuid = h.vcenter_uuid', []); } return $query; diff --git a/library/Vspheredb/Web/Table/Objects/NetworkAdaptersTable.php b/library/Vspheredb/Web/Table/Objects/NetworkAdaptersTable.php index 6421a9df..06e10b29 100644 --- a/library/Vspheredb/Web/Table/Objects/NetworkAdaptersTable.php +++ b/library/Vspheredb/Web/Table/Objects/NetworkAdaptersTable.php @@ -2,64 +2,53 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\DbObject\DistributedVirtualPortgroup; +use Zend_Db_Select; class NetworkAdaptersTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/vm'; + protected ?string $baseUrl = 'vspheredb/vm'; - /** @var DistributedVirtualPortgroup|null */ - protected $portGroup; + protected ?DistributedVirtualPortgroup $portGroup = null; - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->join( - ['vm' => 'virtual_machine'], - 'o.uuid = vm.uuid', - [] - )->join( - ['vh' => 'vm_hardware'], - 'vh.vm_uuid = vm.uuid', - [] - )->join( - ['vna' => 'vm_network_adapter'], - 'vna.vm_uuid = vh.vm_uuid AND vna.hardware_key = vh.hardware_key', - [] - ); + $query = $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []) + ->join(['vh' => 'vm_hardware'], 'vh.vm_uuid = vm.uuid', []) + ->join( + ['vna' => 'vm_network_adapter'], + 'vna.vm_uuid = vh.vm_uuid AND vna.hardware_key = vh.hardware_key', + [] + ); if ($this->portGroup) { - $query->where( - 'portgroup_uuid = ?', - $this->portGroup->get('uuid') - ); + $query->where('portgroup_uuid = ?', $this->portGroup->get('uuid')); } return $query; } - public function filterPortGroup(DistributedVirtualPortgroup $portGroup) + public function filterPortGroup(DistributedVirtualPortgroup $portGroup): static { $this->portGroup = $portGroup; return $this; } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createOverallStatusColumn(), $this->createColumn('port_key', $this->translate('Port'), 'vna.port_key'), $this->createObjectNameColumn(), - $this->createColumn('label', $this->translate('Interface'), [ - 'vh.label', - ]), + $this->createColumn('label', $this->translate('Interface'), ['vh.label']) ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'port_key', diff --git a/library/Vspheredb/Web/Table/Objects/ObjectsTable.php b/library/Vspheredb/Web/Table/Objects/ObjectsTable.php index 38d470be..330c7aeb 100644 --- a/library/Vspheredb/Web/Table/Objects/ObjectsTable.php +++ b/library/Vspheredb/Web/Table/Objects/ObjectsTable.php @@ -7,6 +7,7 @@ use Icinga\Module\Vspheredb\Db\DbUtil; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\Web\Table\BaseTable; +use Icinga\Module\Vspheredb\Web\Table\SimpleColumn; use Icinga\Module\Vspheredb\Web\Table\TableWithParentFilter; use Icinga\Module\Vspheredb\Web\Table\TableWithVCenterFilter; use Icinga\Module\Vspheredb\Web\Widget\OverallStatusRenderer; @@ -14,9 +15,7 @@ abstract class ObjectsTable extends BaseTable implements TableWithVCenterFilter, TableWithParentFilter { - protected $searchColumns = [ - 'object_name', - ]; + protected $searchColumns = ['object_name']; /** @deprecated */ protected $filterVCenter; @@ -24,35 +23,32 @@ abstract class ObjectsTable extends BaseTable implements TableWithVCenterFilter, /** @deprecated */ protected $parentUuids; - protected $baseUrl; + protected ?string $baseUrl = null; - protected $overallStatusRenderer; + protected ?OverallStatusRenderer $overallStatusRenderer = null; - public function filterParentUuids(array $uuids) + public function filterParentUuids(array $uuids): static { $this->getQuery()->where('o.parent_uuid IN (?)', $uuids); return $this; } - public function filterVCenter(VCenter $vCenter): self + public function filterVCenter(VCenter $vCenter): static { return $this->filterVCenterUuids([$vCenter->getUuid()]); } - public function filterVCenterUuids(array $uuids): self + public function filterVCenterUuids(array $uuids): static { if (empty($uuids)) { $this->getQuery()->where('1 = 0'); + return $this; } $db = $this->db(); - if ($this instanceof VCenterSummaryTable) { - $column = 'vc.instance_uuid'; - } else { - $column = 'o.vcenter_uuid'; - } + $column = $this instanceof VCenterSummaryTable ? 'vc.instance_uuid' : 'o.vcenter_uuid'; if (count($uuids) === 1) { $this->getQuery()->where("$column = ?", DbUtil::quoteBinaryCompat(array_shift($uuids), $db)); } else { @@ -62,28 +58,24 @@ public function filterVCenterUuids(array $uuids): self return $this; } - protected function overallStatusRenderer() + protected function overallStatusRenderer(): OverallStatusRenderer { - if ($this->overallStatusRenderer === null) { - $this->overallStatusRenderer = new OverallStatusRenderer(); - } - - return $this->overallStatusRenderer; + return $this->overallStatusRenderer ??= new OverallStatusRenderer(); } - protected function createOverallStatusColumn() + protected function createOverallStatusColumn(): SimpleColumn { return $this->createColumn('overall_status', $this->translate('Status'), 'o.overall_status') ->setRenderer($this->overallStatusRenderer()) ->setDefaultSortDirection('DESC'); } - protected function createObjectNameColumn() + protected function createObjectNameColumn(): SimpleColumn { return $this->createColumn('object_name', $this->translate('Name'), [ 'object_name' => 'o.object_name', 'overall_status' => 'o.overall_status', - 'uuid' => 'o.uuid', + 'uuid' => 'o.uuid' ])->setRenderer(function ($row) { $row->object_name = Anonymizer::anonymizeString($row->object_name); if (in_array('overall_status', $this->getChosenColumnNames())) { @@ -92,15 +84,9 @@ protected function createObjectNameColumn() $statusRenderer = $this->overallStatusRenderer(); $result = [$statusRenderer($row)]; } - if ($this->baseUrl === null) { - $result[] = $row->object_name; - } else { - $result[] = Link::create( - $row->object_name, - $this->baseUrl, - ['uuid' => Uuid::fromBytes($row->uuid)->toString()] - ); - } + $result[] = $this->baseUrl === null + ? $row->object_name + : Link::create($row->object_name, $this->baseUrl, ['uuid' => Uuid::fromBytes($row->uuid)->toString()]); return $result; }); diff --git a/library/Vspheredb/Web/Table/Objects/PercentObjectsTable.php b/library/Vspheredb/Web/Table/Objects/PercentObjectsTable.php new file mode 100644 index 00000000..4d60b4d7 --- /dev/null +++ b/library/Vspheredb/Web/Table/Objects/PercentObjectsTable.php @@ -0,0 +1,21 @@ +$name; + $percent = $row->{"{$name}_percent"}; + + return sprintf('%s (%s)', Format::bytes($bytes, Format::STANDARD_IEC), $this->formatPercent($percent)); + } + + protected function formatPercent(string $value): string + { + return sprintf('%0.2f%%', $value); + } +} diff --git a/library/Vspheredb/Web/Table/Objects/PortGroupsTable.php b/library/Vspheredb/Web/Table/Objects/PortGroupsTable.php index fe1310f5..8dfc3e9b 100644 --- a/library/Vspheredb/Web/Table/Objects/PortGroupsTable.php +++ b/library/Vspheredb/Web/Table/Objects/PortGroupsTable.php @@ -3,80 +3,74 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\Json\JsonString; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\DbObject\DistributedVirtualSwitch; use ipl\Html\Html; +use Zend_Db_Select; class PortGroupsTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/portgroup'; + protected ?string $baseUrl = 'vspheredb/portgroup'; - /** @var DistributedVirtualSwitch|null */ - protected $switch; + protected ?DistributedVirtualSwitch $switch = null; - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->join( - ['vdp' => 'distributed_virtual_portgroup'], - 'o.uuid = vdp.uuid', - [] - ); + $query = $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['vdp' => 'distributed_virtual_portgroup'], 'o.uuid = vdp.uuid', []); if ($this->switch) { - $query->where( - 'distributed_virtual_switch_uuid = ?', - $this->switch->get('uuid') - ); + $query->where('distributed_virtual_switch_uuid = ?', $this->switch->get('uuid')); } return $query; } - public function filterSwitch(DistributedVirtualSwitch $switch) + public function filterSwitch(DistributedVirtualSwitch $switch): static { $this->switch = $switch; return $this; } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createOverallStatusColumn(), $this->createObjectNameColumn(), $this->createColumn('vlan', $this->translate('VLAN'), [ 'vdp.vlan', - 'vdp.vlan_ranges', - ])->setRenderer(function ($row) { - if ($row->vlan === null) { + 'vdp.vlan_ranges' + ]) + ->setRenderer(function ($row) { + if ($row->vlan !== null) { + return $row->vlan; + } + if ($row->vlan_ranges === null) { return '-'; - } else { - $ranges = []; - foreach (JsonString::decode($row->vlan_ranges) as $range) { - if (! empty($ranges)) { - $ranges[] = Html::tag('br'); - } - $ranges[] = sprintf( - '%s - %s', - $range->start, - $range->end - ); - } + } - return $ranges; + $ranges = []; + foreach (JsonString::decode($row->vlan_ranges) as $range) { + if (! empty($ranges)) { + $ranges[] = Html::tag('br'); + } + $ranges[] = sprintf( + '%s - %s', + $range->start, + $range->end + ); } - } else { - return $row->vlan; - } - }), - $this->createColumn('num_ports', $this->translate('Ports'), 'vdp.num_ports'), + + return $ranges; + }), + $this->createColumn('num_ports', $this->translate('Ports'), 'vdp.num_ports') ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'overall_status', diff --git a/library/Vspheredb/Web/Table/Objects/ResourcePoolsTable.php b/library/Vspheredb/Web/Table/Objects/ResourcePoolsTable.php index 1c812129..23f747eb 100644 --- a/library/Vspheredb/Web/Table/Objects/ResourcePoolsTable.php +++ b/library/Vspheredb/Web/Table/Objects/ResourcePoolsTable.php @@ -2,42 +2,40 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; +use gipfl\ZfDb\Select; +use Zend_Db_Select; + class ResourcePoolsTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/resourcepool'; + protected ?string $baseUrl = 'vspheredb/resourcepool'; - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createOverallStatusColumn(), $this->createObjectNameColumn(), $this->createColumn('cnt_vms', $this->translate('VMs'), 'COUNT(*)') - ->setDefaultSortDirection('DESC'), + ->setDefaultSortDirection('DESC') ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'overall_status', 'object_name', - 'cnt_vms', + 'cnt_vms' ]; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->where('object_type = ?', 'ResourcePool'); + $query = $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->where('object_type = ?', 'ResourcePool'); if ($this->hasColumn('cnt_vms')) { - $query->joinLeft( - ['vm' => 'virtual_machine'], - 'vm.resource_pool_uuid = o.uuid', - [] - )->group('o.uuid'); + $query->joinLeft(['vm' => 'virtual_machine'], 'vm.resource_pool_uuid = o.uuid', [])->group('o.uuid'); } return $query; diff --git a/library/Vspheredb/Web/Table/Objects/StoragePodTable.php b/library/Vspheredb/Web/Table/Objects/StoragePodTable.php index d09146cc..07a6f37b 100644 --- a/library/Vspheredb/Web/Table/Objects/StoragePodTable.php +++ b/library/Vspheredb/Web/Table/Objects/StoragePodTable.php @@ -3,96 +3,76 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Link; -use Icinga\Module\Vspheredb\Db; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Util; use Icinga\Module\Vspheredb\Web\Widget\MemoryUsage; use Icinga\Util\Format; use ipl\Html\Html; +use Zend_Db_Select; -class StoragePodTable extends ObjectsTable +class StoragePodTable extends PercentObjectsTable { - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createOverallStatusColumn(), + $this->createColumn('object_name', $this->translate('Name'), [ - 'object_name' => 'o.object_name', - 'uuid' => 'o.uuid', - 'cnt_datastore' => 'COUNT(dso.uuid)', - ])->setRenderer(function ($row) { - $cntDs = (int) $row->cnt_datastore; - if ($cntDs === 0) { - $dsCount = 'no datastore'; - } elseif ($cntDs === 1) { - $dsCount = '1 datastore'; - } else { - $dsCount = sprintf($this->translate('%s datastores'), $cntDs); - } - return Link::create( - [ - $row->object_name, - ' ', - Html::tag('small', $dsCount) - ], - 'vspheredb/datastores', - Util::uuidParams($row->uuid) - ); - }), - $this->createColumn('free_space', $this->translate('Free'), 'sp.free_space') + 'object_name' => 'o.object_name', + 'uuid' => 'o.uuid', + 'cnt_datastore' => 'COUNT(dso.uuid)' + ]) ->setRenderer(function ($row) { - return Format::bytes($row->free_space, Format::STANDARD_IEC); + $cntDs = (int) $row->cnt_datastore; + $dsCount = match ($cntDs) { + 0 => 'no datastore', + 1 => '1 datastore', + default => sprintf($this->translate('%s datastores'), $cntDs) + }; + + return Link::create( + [$row->object_name, ' ', Html::tag('small', $dsCount)], + 'vspheredb/datastores', + Util::uuidParams($row->uuid) + ); }), + + $this->createColumn('free_space', $this->translate('Free'), 'sp.free_space') + ->setRenderer(fn($row) => Format::bytes($row->free_space, Format::STANDARD_IEC)), + $this->createColumn('free_space_percent', $this->translate('Free (%)'), [ - 'free_space_percent' => '(sp.free_space / sp.capacity) * 100' - ])->setRenderer(function ($row) { - return $this->formatPercent($row->free_space_percent); - }), + 'free_space_percent' => '(sp.free_space / sp.capacity) * 100' + ]) + ->setRenderer(fn($row) => $this->formatPercent($row->free_space_percent)), + $this->createColumn('size', $this->translate('Size'), 'sp.capacity') - ->setRenderer(function ($row) { - return Format::bytes($row->capacity, Format::STANDARD_IEC); - }), + ->setRenderer(fn($row) => Format::bytes($row->capacity, Format::STANDARD_IEC)), + $this->createColumn('usage', $this->translate('Usage'), [ 'uuid' => 'o.uuid', 'free_space' => 'sp.free_space', - 'capacity' => 'sp.capacity', - ])->setRenderer(function ($row) { - /** @var Db $connection */ - $div = 1024 * 1024; - $usage = new MemoryUsage(($row->capacity - $row->free_space) / $div, $row->capacity / $div); + 'capacity' => 'sp.capacity' + ]) + ->setRenderer(function ($row) { + $div = 1024 * 1024; - return $usage; - })->setSortExpression( - '1 - (sp.free_space / sp.capacity)' - )->setDefaultSortDirection('DESC'), + return new MemoryUsage(($row->capacity - $row->free_space) / $div, $row->capacity / $div); + }) + ->setSortExpression('1 - (sp.free_space / sp.capacity)') + ->setDefaultSortDirection('DESC') ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'overall_status', 'object_name', - 'usage', + 'usage' ]; } - protected function formatBytesPercent($row, $name) - { - $bytes = $row->$name; - $percent = $row->{"{$name}_percent"}; - return sprintf( - '%s (%s)', - Format::bytes($bytes, Format::STANDARD_IEC), - $this->formatPercent($percent) - ); - } - - protected function formatPercent($value) - { - return sprintf('%0.2f%%', $value); - } - - public function sortBy($columns) + public function sortBy(array|string $columns): static { parent::sortBy($columns); @@ -101,28 +81,12 @@ public function sortBy($columns) return $this; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->join( - ['sp' => 'storage_pod'], - 'o.uuid = sp.uuid', - [] - )->joinLeft( - ['dso' => 'object'], - 'dso.parent_uuid= o.uuid', - [] - )->group('o.uuid'); - - if ($this->parentUuids) { - $query->where('o.parent_uuid IN (?)', $this->parentUuids); - } - if ($this->filterVCenter) { - $query->where('o.vcenter_uuid = ?', $this->filterVCenter->getUuid()); - } - - return $query; + return $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['sp' => 'storage_pod'], 'o.uuid = sp.uuid', []) + ->joinLeft(['dso' => 'object'], 'dso.parent_uuid= o.uuid', []) + ->group('o.uuid'); } } diff --git a/library/Vspheredb/Web/Table/Objects/SwitchesTable.php b/library/Vspheredb/Web/Table/Objects/SwitchesTable.php index 11ddab74..3250ceb5 100644 --- a/library/Vspheredb/Web/Table/Objects/SwitchesTable.php +++ b/library/Vspheredb/Web/Table/Objects/SwitchesTable.php @@ -2,36 +2,32 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; +use gipfl\ZfDb\Select; +use Zend_Db_Select; + class SwitchesTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/switch'; + protected ?string $baseUrl = 'vspheredb/switch'; - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - $this->getRequiredDbColumns() - )->join( - ['vds' => 'distributed_virtual_switch'], - 'o.uuid = vds.uuid', - [] - ); - - return $query; + return $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['vds' => 'distributed_virtual_switch'], 'o.uuid = vds.uuid', []); } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createOverallStatusColumn(), $this->createObjectNameColumn(), $this->createColumn('num_hosts', $this->translate('Hosts'), 'vds.num_hosts'), $this->createColumn('num_ports', $this->translate('Ports'), 'vds.num_ports'), - $this->createColumn('max_ports', $this->translate('Max Ports'), 'vds.max_ports'), + $this->createColumn('max_ports', $this->translate('Max Ports'), 'vds.max_ports') ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'overall_status', diff --git a/library/Vspheredb/Web/Table/Objects/VCenterServersTable.php b/library/Vspheredb/Web/Table/Objects/VCenterServersTable.php index 277a9689..073f5e4c 100644 --- a/library/Vspheredb/Web/Table/Objects/VCenterServersTable.php +++ b/library/Vspheredb/Web/Table/Objects/VCenterServersTable.php @@ -6,14 +6,19 @@ use Evenement\EventEmitterTrait; use gipfl\IcingaWeb2\Icon; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Polling\ApiConnection; use Icinga\Module\Vspheredb\Web\Form\DisableServerForm; use Icinga\Module\Vspheredb\Web\Form\EnableServerForm; use Icinga\Module\Vspheredb\Web\Table\BaseTable; use Icinga\Module\Vspheredb\Web\Table\SimpleColumn; +use ipl\Html\Attributes; use ipl\Html\Html; use ipl\Stdlib\Events; -use Psr\Http\Message\RequestInterface; +use ipl\Html\HtmlElement; +use ipl\Html\Text; +use Psr\Http\Message\ServerRequestInterface; +use Zend_Db_Select; class VCenterServersTable extends BaseTable { @@ -21,16 +26,16 @@ class VCenterServersTable extends BaseTable public const ON_FORM_ACTION = 'formAction'; - protected $request; + protected ?ServerRequestInterface $request = null; - protected $serverConnections; + protected ?array $serverConnections = null; - public function setRequest(RequestInterface $request) + public function setRequest(ServerRequestInterface $request): void { $this->request = $request; } - public function setServerConnections($connections) + public function setServerConnections(?array $connections): void { $this->serverConnections = $connections; } @@ -43,35 +48,22 @@ public function setServerConnections($connections) */ protected function getConnectionStatusIcon(int $serverId, bool $enabled): Icon { - if (isset($this->serverConnections[$serverId])) { - $conn = end($this->serverConnections[$serverId]); - switch ($conn->state) { - case ApiConnection::STATE_CONNECTED: - return Icon::create('ok'); - case ApiConnection::STATE_LOGIN: - case ApiConnection::STATE_INIT: - return Icon::create('spinner'); - case ApiConnection::STATE_FAILING: - return Icon::create('warning-empty'); - case ApiConnection::STATE_STOPPING: - return Icon::create('cancel'); - } - - return Icon::create('off'); - } else { - if ($enabled) { - return Icon::create('help'); - } else { - return Icon::create('off'); - } + if (! isset($this->serverConnections[$serverId])) { + return $enabled ? Icon::create('help') : Icon::create('off'); } + + return match (end($this->serverConnections[$serverId])->state) { + ApiConnection::STATE_CONNECTED => Icon::create('ok'), + ApiConnection::STATE_LOGIN, ApiConnection::STATE_INIT => Icon::create('spinner'), + ApiConnection::STATE_FAILING => Icon::create('warning-empty'), + ApiConnection::STATE_STOPPING => Icon::create('cancel'), + default => Icon::create('off') + }; } - protected function initialize() + protected function initialize(): void { - $this->addAttributes([ - 'class' => 'table-vcenter-servers', - ]); + $this->addAttributes(Attributes::create(['class' => 'table-vcenter-servers'])); $this->addAvailableColumns([ (new SimpleColumn('server', $this->translate('Server'), [ 'id' => 'vcs.id', @@ -79,44 +71,41 @@ protected function initialize() 'username' => 'vcs.username', 'scheme' => 'vcs.scheme', 'enabled' => 'vcs.enabled', - 'vcenter' => 'vc.name', - ]))->setRenderer(function ($row) { - $td = Html::tag('td', ['class' => 'column-server']); - $td->add(Link::create($this->makeUrl($row), 'vspheredb/vcenter/server', ['id' => $row->id])); - $td->add(Html::tag('br')); - $td->add($row->vcenter); - - return $td; - })->setDefaultSortDirection('DESC'), - (new SimpleColumn('enabled', $this->translate('Status'), [ - 'vcs.enabled', - 'vcs.id', - ]))->setRenderer(function ($row) { - if ($row->enabled === 'y') { - $form = new DisableServerForm($row->id, $this->db()); - } else { - $form = new EnableServerForm($row->id, $this->db()); - } - $form->addAttributes([ - 'data-base-target' => '_self' - ]); - $form->on($form::ON_SUCCESS, function () { - $this->emit(self::ON_FORM_ACTION); - }); - $form->handleRequest($this->request); - $form->ensureAssembled(); - $td = Html::tag('td', [ - 'class' => 'column-enabled' - ], $form); - if ($this->serverConnections !== null) { - $td->add([' ', $this->getConnectionStatusIcon($row->id, $row->enabled === 'y'), ' ']); - } - return $td; - }), + 'vcenter' => 'vc.name' + ])) + ->setRenderer(function ($row) { + return Html::tag('td', ['class' => 'column-server']) + ->addHtml( + Link::create($this->makeUrl($row), 'vspheredb/vcenter/server', ['id' => $row->id]), + Html::tag('br'), + new Text($row->vcenter) + ); + }) + ->setDefaultSortDirection('DESC'), + (new SimpleColumn('enabled', $this->translate('Status'), ['vcs.enabled', 'vcs.id'])) + ->setRenderer(function ($row) { + $form = $row->enabled === 'y' + ? new DisableServerForm($row->id, $this->db()) + : new EnableServerForm($row->id, $this->db()); + + $form->addAttributes(Attributes::create(['data-base-target' => '_self'])) + ->on($form::ON_SUBMIT, function () { + $this->emit(self::ON_FORM_ACTION); + }) + ->handleRequest($this->request) + ->ensureAssembled(); + + $td = Html::tag('td', ['class' => 'column-enabled'], $form); + if ($this->serverConnections !== null) { + $td->add([' ', $this->getConnectionStatusIcon($row->id, $row->enabled === 'y'), ' ']); + } + + return $td; + }) ]); } - public function renderRow($row) + public function renderRow($row): HtmlElement { $tr = parent::renderRow($row); if ($row->enabled === 'n') { @@ -126,26 +115,15 @@ public function renderRow($row) return $tr; } - protected function makeUrl($row) + protected function makeUrl(object $row): string { - return sprintf( - '%s://%s@%s', - $row->scheme, - rawurlencode($row->username), - $row->host - ); + return sprintf('%s://%s@%s', $row->scheme, rawurlencode($row->username), $row->host); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - ['vcs' => 'vcenter_server'], - $this->getRequiredDbColumns() - )->joinLeft( - ['vc' => 'vcenter'], - // 'vc.instance_uuid = vcs.vcenter_uuid', - 'vc.id = vcs.vcenter_id', - [] - ); + return $this->db()->select() + ->from(['vcs' => 'vcenter_server'], $this->getRequiredDbColumns()) + ->joinLeft(['vc' => 'vcenter'], /* 'vc.instance_uuid = vcs.vcenter_uuid',*/ 'vc.id = vcs.vcenter_id', []); } } diff --git a/library/Vspheredb/Web/Table/Objects/VCenterSummaryTable.php b/library/Vspheredb/Web/Table/Objects/VCenterSummaryTable.php index 046b415d..d9f57161 100644 --- a/library/Vspheredb/Web/Table/Objects/VCenterSummaryTable.php +++ b/library/Vspheredb/Web/Table/Objects/VCenterSummaryTable.php @@ -3,32 +3,36 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Format; use Icinga\Module\Vspheredb\Monitoring\Health\ServerConnectionInfo; use Icinga\Module\Vspheredb\Util; +use Icinga\Module\Vspheredb\Web\Table\SimpleColumn; use Icinga\Module\Vspheredb\Web\Widget\CpuUsage; use Icinga\Module\Vspheredb\Web\Widget\MemoryUsage; use Icinga\Module\Vspheredb\Web\Widget\VCenterConnectionStatusIcon; use ipl\Html\Html; +use ipl\Html\HtmlElement; use Ramsey\Uuid\Uuid; +use Zend_Db_Select; class VCenterSummaryTable extends ObjectsTable { protected $searchColumns = [ - 'name', + 'name' ]; - protected $baseUrl = 'vspheredb/vcenter'; + protected ?string $baseUrl = 'vspheredb/vcenter'; - protected $baseUrlHosts = 'vspheredb/hosts'; + protected string $baseUrlHosts = 'vspheredb/hosts'; - protected $groupBy = 'o.vcenter_uuid'; + protected string $groupBy = 'o.vcenter_uuid'; - protected $groupByAlias = 'name'; + protected string $groupByAlias = 'name'; - protected $nameColumn = 'vc.name'; + protected string $nameColumn = 'vc.name'; - /** @var array> */ - protected $connections; + /** @var ?array> */ + protected ?array $connections = null; /** * @param array> $connections @@ -37,10 +41,11 @@ class VCenterSummaryTable extends ObjectsTable public function setConnections(array $connections): self { $this->connections = $connections; + return $this; } - protected function getExtraIcons($row) + protected function getExtraIcons(object $row): ?HtmlElement { if ($this->connections === null) { return null; @@ -59,174 +64,176 @@ protected function getExtraIcons($row) return $icons; } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ $this->groupByAlias, 'cpu', 'memory', - 'datastore_usage', + 'datastore_usage' ]; } - protected function initialize() + protected function initialize(): void { $this->setAttribute('data-base-target', '_self'); - $this->addAvailableColumns([ - $this->createGroupingColumn(), - ]); + $this->addAvailableColumns([$this->createGroupingColumn()]); $this->addHostColumns(); $this->addDatastoreColumns(); $this->addVCenterColumns(); } - protected function createGroupingColumn() + protected function createGroupingColumn(): SimpleColumn { return $this->createColumn($this->groupByAlias, $this->getGroupingTitle(), [ - 'name' => $this->nameColumn, - 'uuid' => $this->groupBy, - ] + $this->getHostCountColumns())->setRenderer(function ($row) { - $link = Link::create( + 'name' => $this->nameColumn, + 'uuid' => $this->groupBy + ] + $this->getHostCountColumns()) + ->setRenderer(fn($row) => [ + $this->getExtraIcons($row), + Link::create( $row->{$this->groupByAlias}, $this->baseUrl, $this->getFilterParams($row), ['data-base-target' => '_next'] - ); - - return [ - $this->getExtraIcons($row), - $link, - $this->renderHostSummaries($row), - ]; - }); + ), + $this->renderHostSummaries($row) + ]); } - protected function hasChosenColumn($name) + protected function hasChosenColumn($name): bool { return in_array($name, $this->getChosenColumnNames()); } - protected function addHostColumns() + protected function addHostColumns(): void { $this->addAvailableColumns([ $this->createColumn('hosts_cnt', $this->translate('Hosts'), 'SUM(hosts_cnt)') - ->setRenderer(function ($row) { - return Html::tag('td', ['class' => 'text-right'], $row->hosts_cnt); - }) + ->setRenderer(fn($row) => Html::tag('td', ['class' => 'text-right'], $row->hosts_cnt)) ->setDefaultSortDirection('DESC'), - $this->createColumn( - 'hosts_status', - $this->translate('Hosts Status'), - $this->getHostCountColumns() - )->setRenderer(function ($row) { - $result = []; - $uuid = Uuid::fromBytes($row->uuid)->toString(); - foreach (['green', 'gray', 'yellow', 'red'] as $state) { - $column = "hosts_cnt_overall_$state"; - if ($row->$column > 0) { - $result[] = Link::create($row->$column, $this->baseUrlHosts, [ - 'vcenter' => $uuid, - 'overall_status' => $state - ], ['class' => ['state', $state]]); + + $this->createColumn('hosts_status', $this->translate('Hosts Status'), $this->getHostCountColumns()) + ->setRenderer(function ($row) { + $result = []; + $uuid = Uuid::fromBytes($row->uuid)->toString(); + foreach (['green', 'gray', 'yellow', 'red'] as $state) { + $column = "hosts_cnt_overall_$state"; + if ($row->$column > 0) { + $result[] = Link::create( + $row->$column, + $this->baseUrlHosts, + [ + 'vcenter' => $uuid, + 'overall_status' => $state + ], + ['class' => ['state', $state]] + ); + } + } + + if (empty($result)) { + return '-'; } - } - if (empty($result)) { - return '-'; - } else { return $result; - } - })->setSortExpression([ - "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)", - "SUM(CASE WHEN ho.overall_status = 'yellow' THEN 1 ELSE 0 END)", - "SUM(CASE WHEN ho.overall_status = 'gray' THEN 1 ELSE 0 END)", - "SUM(CASE WHEN ho.overall_status = 'green' THEN 1 ELSE 0 END)", - ])->setDefaultSortDirection('DESC'), + }) + ->setSortExpression([ + "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)", + "SUM(CASE WHEN ho.overall_status = 'yellow' THEN 1 ELSE 0 END)", + "SUM(CASE WHEN ho.overall_status = 'gray' THEN 1 ELSE 0 END)", + "SUM(CASE WHEN ho.overall_status = 'green' THEN 1 ELSE 0 END)" + ]) + ->setDefaultSortDirection('DESC'), + $this->createColumn('cpu', $this->translate('CPU'), [ 'used_mhz' => 'SUM(hqs.overall_cpu_usage)', - 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)', - ])->setRenderer(function ($row) { - $bar = new CpuUsage($row->used_mhz, $row->total_mhz); - if ($this->hasChosenColumn('overall_cpu_usage') || $this->hasChosenColumn('hardware_cpu_mhz')) { - $bar->showLabels(false); - } - return $bar; - })->setSortExpression( - '(overall_cpu_usage / total_mhz)' - )->setDefaultSortDirection('DESC'), - $this->createColumn('overall_cpu_usage', $this->translate('Used'), 'SUM(hqs.overall_cpu_usage)') + 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)' + ]) ->setRenderer(function ($row) { - return Format::mhz($row->overall_cpu_usage); - })->setDefaultSortDirection('DESC'), + $bar = new CpuUsage($row->used_mhz, $row->total_mhz); + if ($this->hasChosenColumn('overall_cpu_usage') || $this->hasChosenColumn('hardware_cpu_mhz')) { + $bar->showLabels(false); + } + + return $bar; + }) + ->setSortExpression('(overall_cpu_usage / total_mhz)') + ->setDefaultSortDirection('DESC'), + + $this->createColumn('overall_cpu_usage', $this->translate('Used'), 'SUM(hqs.overall_cpu_usage)') + ->setRenderer(fn($row) => Format::mhz($row->overall_cpu_usage)) + ->setDefaultSortDirection('DESC'), + $this->createColumn( 'hardware_cpu_mhz', $this->translate('Capacity'), 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)' - )->setRenderer(function ($row) { - return Format::mhz($row->hardware_cpu_mhz); - })->setDefaultSortDirection('DESC'), + ) + ->setRenderer(fn($row) => Format::mhz($row->hardware_cpu_mhz)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('hardware_cpu_cores', $this->translate('Cores'), 'SUM(h.hardware_cpu_cores)') - ->setRenderer(function ($row) { - return Html::tag('td', ['class' => 'text-right'], $row->hardware_cpu_cores); - }) + ->setRenderer(fn($row) => Html::tag('td', ['class' => 'text-right'], $row->hardware_cpu_cores)) ->setDefaultSortDirection('DESC'), $this->createColumn('memory', $this->translate('Memory'), [ 'memory_used_mb' => 'SUM(hqs.overall_memory_usage_mb)', - 'memory_total_mb' => 'SUM(h.hardware_memory_size_mb)', - ])->setRenderer(function ($row) { - $bar = new MemoryUsage($row->memory_used_mb, $row->memory_total_mb); - if ($this->hasChosenColumn('overall_memory_usage') || $this->hasChosenColumn('hardware_memorymb')) { - $bar->showLabels(false); - } - return $bar; - })->setSortExpression( - '(memory_used_mb / memory_total_mb)' - )->setDefaultSortDirection('DESC'), - $this->createColumn('overall_memory_usage', $this->translate('Used'), 'SUM(hqs.overall_memory_usage_mb)') + 'memory_total_mb' => 'SUM(h.hardware_memory_size_mb)' + ]) ->setRenderer(function ($row) { - return Format::mBytes($row->overall_memory_usage); - })->setDefaultSortDirection('DESC'), + $bar = new MemoryUsage($row->memory_used_mb, $row->memory_total_mb); + if ($this->hasChosenColumn('overall_memory_usage') || $this->hasChosenColumn('hardware_memorymb')) { + $bar->showLabels(false); + } + + return $bar; + }) + ->setSortExpression('(memory_used_mb / memory_total_mb)') + ->setDefaultSortDirection('DESC'), + + $this->createColumn('overall_memory_usage', $this->translate('Used'), 'SUM(hqs.overall_memory_usage_mb)') + ->setRenderer(fn($row) => Format::mBytes($row->overall_memory_usage)) + ->setDefaultSortDirection('DESC'), + $this->createColumn('hardware_memory_mb', $this->translate('Capacity')) - ->setRenderer(function ($row) { - return Format::mBytes($row->hardware_memory_mb); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mBytes($row->hardware_memory_mb)) + ->setDefaultSortDirection('DESC') ]); } - protected function addDatastoreColumns() + protected function addDatastoreColumns(): void { $this->addAvailableColumns([ $this->createColumn('datastore_usage', $this->translate('Storage'), [ 'ds_capacity' => 'ds.ds_capacity', - 'ds_free_space' => 'ds.ds_free_space', - ])->setRenderer(function ($row) { - return new MemoryUsage( + 'ds_free_space' => 'ds.ds_free_space' + ]) + ->setRenderer(fn($row) => new MemoryUsage( ($row->ds_capacity - $row->ds_free_space) / 1000000, $row->ds_capacity / 1000000 - ); - })->setSortExpression('(ds.ds_capacity - ds.ds_free_space) / ds.ds_capacity'), + )) + ->setSortExpression('(ds.ds_capacity - ds.ds_free_space) / ds.ds_capacity') ]); } - protected function addVCenterColumns() + protected function addVCenterColumns(): void { $this->addAvailableColumns([ $this->createColumn('vcenter_software', $this->translate('Software'), [ - 'software_name' => 'vc.api_name', - 'software_version' => 'vc.version', - ])->setRenderer(function ($row) { + 'software_name' => 'vc.api_name', + 'software_version' => 'vc.version' + ]) // VMware ESXi -> ESXi - return \sprintf( + ->setRenderer(fn($row) => sprintf( '%s (%s)', - \preg_replace('/^VMware /', '', $row->software_name), + preg_replace('/^VMware /', '', $row->software_name), $row->software_version - ); - }), + )) ]); } - protected function renderHostSummaries($row) + protected function renderHostSummaries(object $row): ?array { $params = $this->getFilterParams($row); @@ -248,9 +255,12 @@ protected function renderHostSummaries($row) foreach (['red', 'yellow', 'gray', 'green'] as $state) { $column = "hosts_cnt_overall_$state"; if ($row->$column > 0) { - $result[] = Link::create($row->$column, 'vspheredb/hosts', $params + [ - 'overall_status' => $state - ], ['class' => ['state', $state]]); + $result[] = Link::create( + $row->$column, + 'vspheredb/hosts', + $params + ['overall_status' => $state], + ['class' => ['state', $state]] + ); } } } @@ -258,28 +268,28 @@ protected function renderHostSummaries($row) if (empty($result)) { return null; } + return [ Html::tag('br'), - Html::tag('small', $result), + Html::tag('small', $result) ]; } - protected function getHostCountColumns() + protected function getHostCountColumns(): array { return [ - 'hosts_cnt' => 'COUNT(DISTINCT ho.uuid)', + 'hosts_cnt' => 'COUNT(DISTINCT ho.uuid)', 'hosts_cnt_overall_gray' => "SUM(CASE WHEN ho.overall_status = 'gray' THEN 1 ELSE 0 END)", 'hosts_cnt_overall_green' => "SUM(CASE WHEN ho.overall_status = 'green' THEN 1 ELSE 0 END)", 'hosts_cnt_overall_yellow' => "SUM(CASE WHEN ho.overall_status = 'yellow' THEN 1 ELSE 0 END)", - 'hosts_cnt_overall_red' => "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)", + 'hosts_cnt_overall_red' => "SUM(CASE WHEN ho.overall_status = 'red' THEN 1 ELSE 0 END)" ]; } - protected function prepareHostsQuery() + protected function prepareHostsQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - ['h' => 'host_system'], - [ + return $this->db()->select() + ->from(['h' => 'host_system'], [ 'vcenter_uuid' => 'h.vcenter_uuid', 'hosts_cnt' => 'COUNT(DISTINCT h.uuid)', 'hosts_cnt_overall_gray' => "SUM(CASE WHEN ho.overall_status = 'gray' THEN 1 ELSE 0 END)", @@ -296,64 +306,48 @@ protected function prepareHostsQuery() 'memory_used_mb' => 'SUM(hqs.overall_memory_usage_mb)', 'memory_total_mb' => 'SUM(h.hardware_memory_size_mb)', 'overall_memory_usage' => 'SUM(hqs.overall_memory_usage_mb)', - 'hardware_memory_mb' => 'SUM(h.hardware_memory_size_mb)', - ] - )->join( - ['ho' => 'object'], - 'ho.uuid = h.uuid', - [] - )->join( - ['hqs' => 'host_quick_stats'], - 'hqs.uuid = h.uuid', - [] - ) + 'hardware_memory_mb' => 'SUM(h.hardware_memory_size_mb)' + ]) + ->join(['ho' => 'object'], 'ho.uuid = h.uuid', []) + ->join(['hqs' => 'host_quick_stats'], 'hqs.uuid = h.uuid', []) ->group('h.vcenter_uuid'); } - protected function prepareDatastoreQuery() + protected function prepareDatastoreQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - // TODO: Join object? - ['ds' => 'datastore'], - [ + // TODO: Join object? + return $this->db()->select() + ->from(['ds' => 'datastore'], [ 'vcenter_uuid' => 'ds.vcenter_uuid', 'ds_capacity' => 'SUM(ds.capacity)', 'ds_free_space' => 'SUM(ds.free_space)', - 'ds_uncommitted' => 'SUM(ds.uncommitted)', - ] - )->group('ds.vcenter_uuid'); + 'ds_uncommitted' => 'SUM(ds.uncommitted)' + ]) + ->group('ds.vcenter_uuid'); } - protected function prepareQuery() + protected function prepareQuery(): Select|Zend_Db_Select { $vCenterColumns = [ 'uuid' => 'vc.instance_uuid', 'vcenter_id' => 'vc.id', 'name' => 'vc.name', 'software_name' => 'vc.api_name', - 'software_version' => 'vc.version', + 'software_version' => 'vc.version' ]; - return $this->db()->select()->from( - ['vc' => 'vcenter'], - $vCenterColumns + ['h.*', 'ds.*'] - )->joinLeft( - ['ds' => $this->prepareDatastoreQuery()], - 'vc.instance_uuid = ds.vcenter_uuid', - [] - )->joinLeft( - ['h' => $this->prepareHostsQuery()], - 'vc.instance_uuid = h.vcenter_uuid', - [] - ); + return $this->db()->select() + ->from(['vc' => 'vcenter'], $vCenterColumns + ['h.*', 'ds.*']) + ->joinLeft(['ds' => $this->prepareDatastoreQuery()], 'vc.instance_uuid = ds.vcenter_uuid', []) + ->joinLeft(['h' => $this->prepareHostsQuery()], 'vc.instance_uuid = h.vcenter_uuid', []); } - protected function getGroupingTitle() + protected function getGroupingTitle(): string { return $this->translate('VCenter'); } - protected function getFilterParams($row) + protected function getFilterParams($row): array { return ['vcenter' => Util::niceUuid($row->uuid)]; } diff --git a/library/Vspheredb/Web/Table/Objects/VmsGuestDiskUsageTable.php b/library/Vspheredb/Web/Table/Objects/VmsGuestDiskUsageTable.php index 7179264b..f278a26f 100644 --- a/library/Vspheredb/Web/Table/Objects/VmsGuestDiskUsageTable.php +++ b/library/Vspheredb/Web/Table/Objects/VmsGuestDiskUsageTable.php @@ -3,126 +3,113 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Img; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Format; use Icinga\Module\Vspheredb\Web\Widget\SimpleUsageBar; use ipl\Html\Html; +use Zend_Db_Select; class VmsGuestDiskUsageTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/vm'; + protected ?string $baseUrl = 'vspheredb/vm'; protected $searchColumns = [ 'object_name', - 'disk_path', + 'disk_path' ]; - protected $withHistory = false; + protected bool $withHistory = false; - public function filterHost($uuid) + public function filterHost(string $uuid): static { $this->getQuery()->where('vc.runtime_host_uuid = ?', $uuid); return $this; } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createObjectNameColumn(), + $this->createColumn('disk_path', $this->translate('Disk Path'), 'vdu.disk_path'), + $this->createColumn('free_space', $this->translate('Free Space'), 'vdu.free_space') - ->setRenderer(function ($row) { - return Format::bytes($row->free_space); - }), + ->setRenderer(fn($row) => Format::bytes($row->free_space)), + $this->createColumn('capacity', $this->translate('Capacity'), 'vdu.capacity') - ->setRenderer(function ($row) { - return Format::bytes($row->capacity); - }), + ->setRenderer(fn($row) => Format::bytes($row->capacity)), + $this->createColumn('usage', $this->translate('Usage'), [ 'free_space' => 'vdu.free_space', - 'capacity' => 'vdu.capacity', - ])->setRenderer(function ($row) { - $title = sprintf( + 'capacity' => 'vdu.capacity' + ]) + ->setRenderer(fn($row) => new SimpleUsageBar($row->capacity - $row->free_space, $row->capacity, sprintf( '%s free out of %s (%.2F %%)', $row->free_space, $row->capacity, $row->free_space / $row->capacity * 100 - ); - - return new SimpleUsageBar($row->capacity - $row->free_space, $row->capacity, $title); - })->setSortExpression( - '1 - (vdu.free_space / vdu.capacity)' - )->setDefaultSortDirection('DESC'), + ))) + ->setSortExpression('1 - (vdu.free_space / vdu.capacity)') + ->setDefaultSortDirection('DESC') ]); if ($this->withHistory) { $this->addAvailableColumn( - $this->createColumn('history', $this->translate('History'), [ - 'object_name' => 'o.object_name', - ])->setRenderer(function ($row) { - $ciName = str_replace(' ', '_', $row->object_name); - $path = str_replace('/', '_', $row->disk_path); - $path = str_replace(' ', '_', $path); - $ci = $ciName . ':' . $path; - $now = time(); - $end = floor($now / 60) * 60; - $offset = 3600 * 24 * 96; - $duration = 3600 * 12 * 4; - $start = $end - $offset; - $end = $start + $duration; - - return Html::tag( - 'div', - ['class' => 'vm-disk-usage-history'], - Html::tag( + $this->createColumn('history', $this->translate('History'), ['object_name' => 'o.object_name']) + ->setRenderer(function ($row) { + $ciName = str_replace(' ', '_', $row->object_name); + $path = str_replace('/', '_', $row->disk_path); + $path = str_replace(' ', '_', $path); + $ci = $ciName . ':' . $path; + $now = time(); + $end = floor($now / 60) * 60; + $offset = 3600 * 24 * 96; + $duration = 3600 * 12 * 4; + $start = $end - $offset; + $end = $start + $duration; + + return Html::tag( 'div', - ['class' => 'inline-perf-container'], - Img::create( - 'rrd/img', - [ - 'file' => $ci . '.rrd', - 'rnd' => time(), - 'height' => 24 * 6, - 'width' => 80 * 6, - 'start' => $start, - 'end' => $end, - 'template' => 'vm_disk', - ], - ['class' => 'inline-perf-small'] + ['class' => 'vm-disk-usage-history'], + Html::tag( + 'div', + ['class' => 'inline-perf-container'], + Img::create( + 'rrd/img', + [ + 'file' => $ci . '.rrd', + 'rnd' => time(), + 'height' => 24 * 6, + 'width' => 80 * 6, + 'start' => $start, + 'end' => $end, + 'template' => 'vm_disk' + ], + ['class' => 'inline-perf-small'] + ) ) - ) - ); - }) + ); + }) ); } } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $columns = $this->getRequiredDbColumns(); - $query = $this->db()->select()->from( - ['o' => 'object'], - $columns - )->join( - ['vc' => 'virtual_machine'], - 'o.uuid = vc.uuid', - [] - )->join( - ['vdu' => 'vm_disk_usage'], - 'vc.uuid = vdu.vm_uuid', - [] - ); - - return $query; + return $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['vc' => 'virtual_machine'], 'o.uuid = vc.uuid', []) + ->join(['vdu' => 'vm_disk_usage'], 'vc.uuid = vdu.vm_uuid', []); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'object_name', 'disk_path', 'capacity', - 'usage', + 'usage' ]; } } diff --git a/library/Vspheredb/Web/Table/Objects/VmsSnapshotsTable.php b/library/Vspheredb/Web/Table/Objects/VmsSnapshotsTable.php index 13bce23b..8b4d296c 100644 --- a/library/Vspheredb/Web/Table/Objects/VmsSnapshotsTable.php +++ b/library/Vspheredb/Web/Table/Objects/VmsSnapshotsTable.php @@ -3,83 +3,69 @@ namespace Icinga\Module\Vspheredb\Web\Table\Objects; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\Util; +use Zend_Db_Select; class VmsSnapshotsTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/vm'; + protected ?string $baseUrl = 'vspheredb/vm'; protected $searchColumns = [ 'object_name', - 'guest_host_name', + 'guest_host_name' ]; - public function filterHost($uuid) + public function filterHost(string $uuid): static { $this->getQuery()->where('vc.runtime_host_uuid = ?', $uuid); return $this; } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ $this->createColumn('guest_name', $this->translate('Guest hostname'), [ 'object_name' => 'o.object_name', 'uuid' => 'vm.uuid', - 'guest_host_name' => 'vm.guest_host_name', - ])->setRenderer(function ($row) { - if ($row->guest_host_name === null || $row->guest_host_name === $row->object_name) { - $name = $row->object_name; - } else { - $name = sprintf('%s (%s)', $row->object_name, $row->guest_host_name); - } - - return Link::create( - $name, + 'guest_host_name' => 'vm.guest_host_name' + ]) + ->setRenderer(fn($row) => Link::create( + $row->guest_host_name === null || $row->guest_host_name === $row->object_name + ? $row->object_name + : sprintf('%s (%s)', $row->object_name, $row->guest_host_name), $this->baseUrl, Util::uuidParams($row->uuid) - ); - }), + )), + $this->createColumn('cnt', $this->translate('Snapshots'), 'COUNT(*)'), + $this->createColumn('ts_oldest', $this->translate('Oldest'), 'MIN(vms.ts_create)') - ->setRenderer(function ($row) { - return DateFormatter::formatDate($row->ts_oldest / 1000); - }), + ->setRenderer(fn($row) => DateFormatter::formatDate($row->ts_oldest / 1000)), + $this->createColumn('ts_newest', $this->translate('Newest'), 'MAX(vms.ts_create)') - ->setRenderer(function ($row) { - return DateFormatter::formatDate($row->ts_newest / 1000); - }) + ->setRenderer(fn($row) => DateFormatter::formatDate($row->ts_newest / 1000)) ]); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $columns = $this->getRequiredDbColumns(); - $query = $this->db()->select()->from( - ['o' => 'object'], - $columns - )->join( - ['vm' => 'virtual_machine'], - 'o.uuid = vm.uuid', - [] - )->join( - ['vms' => 'vm_snapshot'], - 'vms.vm_uuid = vm.uuid', - [] - )->group('vm.uuid'); - - return $query; + return $this->db()->select() + ->from(['o' => 'object'], $this->getRequiredDbColumns()) + ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []) + ->join(['vms' => 'vm_snapshot'], 'vms.vm_uuid = vm.uuid', []) + ->group('vm.uuid'); } - public function XXgetDefaultColumnNames() + public function XXgetDefaultColumnNames(): array { return [ 'object_name', 'disk_path', 'free_space', - 'capacity', + 'capacity' ]; } } diff --git a/library/Vspheredb/Web/Table/Objects/VmsTable.php b/library/Vspheredb/Web/Table/Objects/VmsTable.php index cb35ebad..36da262c 100644 --- a/library/Vspheredb/Web/Table/Objects/VmsTable.php +++ b/library/Vspheredb/Web/Table/Objects/VmsTable.php @@ -4,36 +4,39 @@ use gipfl\IcingaWeb2\Img; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\Data\Anonymizer; +use Icinga\Module\Vspheredb\Format; +use Icinga\Module\Vspheredb\Web\Table\SimpleColumn; use Icinga\Module\Vspheredb\Web\Widget\DelayedPerfdataRenderer; use Icinga\Module\Vspheredb\Web\Widget\GuestToolsStatusRenderer; use Icinga\Module\Vspheredb\Web\Widget\MemoryUsage; use Icinga\Module\Vspheredb\Web\Widget\PowerStateRenderer; use Icinga\Module\Vspheredb\Web\Widget\Renderer\GuestToolsVersionRenderer; -use Icinga\Module\Vspheredb\Format; use ipl\Html\Html; use Ramsey\Uuid\Uuid; +use Zend_Db_Select; class VmsTable extends ObjectsTable { - protected $baseUrl = 'vspheredb/vm'; + protected ?string $baseUrl = 'vspheredb/vm'; protected $searchColumns = [ 'object_name', 'guest_host_name', 'guest_ip_address', - 'moref', + 'moref' ]; - public function filterHost($uuid) + public function filterHost(string $uuid): static { $this->getQuery()->where('vm.runtime_host_uuid = ?', $uuid); return $this; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { $columns = $this->getRequiredDbColumns(); $wantsHosts = false; @@ -42,97 +45,74 @@ public function prepareQuery() $wantsDisks = false; $wantsDataStores = false; foreach ($columns as $column) { - if (substr($column, 0, 2) === 'h.') { + if (str_starts_with($column, 'h.')) { $wantsHosts = true; } - if (substr($column, 0, 4) === 'vqs.') { + if (str_starts_with($column, 'vqs.')) { $wantsStats = true; } - if (substr($column, 0, 3) === 'vc.') { + if (str_starts_with($column, 'vc.')) { $wantsVCenter = true; } - if (substr($column, 0, 4) === 'vmd.') { + if (str_starts_with($column, 'vmd.')) { $wantsDisks = true; } - if (substr($column, 0, 4) === 'vdu.') { + if (str_starts_with($column, 'vdu.')) { $wantsDataStores = true; } } - $query = $this->db()->select()->from( - ['o' => 'object'], - $columns - )->join( - ['vm' => 'virtual_machine'], - 'o.uuid = vm.uuid', - [] - ); + $query = $this->db()->select() + ->from(['o' => 'object'], $columns) + ->join(['vm' => 'virtual_machine'], 'o.uuid = vm.uuid', []); if ($wantsStats) { - $query->join( - ['vqs' => 'vm_quick_stats'], - 'vqs.uuid = vm.uuid', - [] - ); + $query->join(['vqs' => 'vm_quick_stats'], 'vqs.uuid = vm.uuid', []); } if ($wantsVCenter) { - $query->join( - ['vc' => 'vcenter'], - 'vc.instance_uuid = vm.vcenter_uuid', - [] - ); + $query->join(['vc' => 'vcenter'], 'vc.instance_uuid = vm.vcenter_uuid', []); } if ($wantsHosts) { - $query->joinLeft( - ['h' => 'host_system'], - 'vm.runtime_host_uuid = h.uuid', - [] - ); + $query->joinLeft(['h' => 'host_system'], 'vm.runtime_host_uuid = h.uuid', []); } if ($wantsDataStores) { - $sub = $this->db()->select()->from('vm_datastore_usage', [ - 'vm_uuid' => 'vm_uuid', - 'datastore_capacity' => 'SUM(committed + uncommitted)', - 'datastore_usage' => 'SUM(committed)', - ])->group('vm_uuid'); + $sub = $this->db()->select() + ->from('vm_datastore_usage', [ + 'vm_uuid' => 'vm_uuid', + 'datastore_capacity' => 'SUM(committed + uncommitted)', + 'datastore_usage' => 'SUM(committed)' + ]) + ->group('vm_uuid'); + $query->joinLeft(['vdu' => $sub], 'vdu.vm_uuid = o.uuid', []); } if ($wantsDisks) { - $sub = $this->db()->select()->from('vm_disk', [ - 'vm_uuid' => 'vm_uuid', - 'disk_capacity' => 'SUM(capacity)', - ])->group('vm_uuid'); - $query->joinLeft(['vmd' => $sub], 'vmd.vm_uuid = o.uuid', []); - } + $sub = $this->db()->select() + ->from('vm_disk', ['vm_uuid' => 'vm_uuid', 'disk_capacity' => 'SUM(capacity)']) + ->group('vm_uuid'); - if ($this->parentUuids) { - $query->where('o.parent_uuid IN (?)', $this->parentUuids); - } - if ($this->filterVCenter) { - $query->where('o.vcenter_uuid = ?', $this->filterVCenter->getUuid()); + $query->joinLeft(['vmd' => $sub], 'vmd.vm_uuid = o.uuid', []); } return $query; } - protected function initialize() + protected function initialize(): void { $powerStateRenderer = new PowerStateRenderer(); $guestToolsStatusRenderer = new GuestToolsStatusRenderer(); $guestToolsVersionRenderer = new GuestToolsVersionRenderer(); - $memoryRenderer = function ($row) { - return new MemoryUsage( - $row->guest_memory_usage_mb, - $row->hardware_memorymb, - $row->host_memory_usage_mb - ); - }; + $memoryRenderer = fn($row) => new MemoryUsage( + $row->guest_memory_usage_mb, + $row->hardware_memorymb, + $row->host_memory_usage_mb + ); $memoryColumns = [ 'guest_memory_usage_mb' => 'vqs.guest_memory_usage_mb', 'host_memory_usage_mb' => 'vqs.host_memory_usage_mb', - 'hardware_memorymb' => 'vm.hardware_memorymb', + 'hardware_memorymb' => 'vm.hardware_memorymb' ]; $this->addAvailableColumns([ $this->createColumn('runtime_power_state', $this->translate('Power'), 'vm.runtime_power_state') @@ -142,25 +122,20 @@ protected function initialize() $this->createObjectNameColumn(), - $this->createColumn( - 'guest_tools_status', - $this->translate('Guest Tools'), - 'vm.guest_tools_status' - )->setRenderer($guestToolsStatusRenderer)->setSortExpression('vm.guest_tools_status'), - - $this->createColumn( - 'guest_tools_version', - $this->translate('Tools Version'), - 'vm.guest_tools_version' - ) - ->setRenderer($guestToolsVersionRenderer) - ->setSortExpression( - "CAST(" - . "CASE WHEN guest_tools_version = '2147483647' THEN '1' ELSE guest_tools_version END" - . " AS SIGNED INTEGER)" - ), + $this->createColumn('guest_tools_status', $this->translate('Guest Tools'), 'vm.guest_tools_status') + ->setRenderer($guestToolsStatusRenderer) + ->setSortExpression('vm.guest_tools_status'), + + $this->createColumn('guest_tools_version', $this->translate('Tools Version'), 'vm.guest_tools_version') + ->setRenderer($guestToolsVersionRenderer) + ->setSortExpression( + "CAST(" + . "CASE WHEN guest_tools_version = '2147483647' THEN '1' ELSE guest_tools_version END" + . " AS SIGNED INTEGER)" + ), $this->createColumn('host_name', $this->translate('Host'), 'h.host_name'), + $this->createColumn('vcenter_name', $this->translate('vCenter / ESXi'), 'vc.name'), $this->createColumn('guest_ip_address', $this->translate('Guest IP'), 'vm.guest_ip_address'), @@ -169,30 +144,25 @@ protected function initialize() ->setDefaultSortDirection('DESC'), $this->createColumn('cpu_usage', $this->translate('CPU Usage'), 'vqs.overall_cpu_usage') - ->setRenderer(function ($row) { - return Format::mhz($row->cpu_usage); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mhz($row->cpu_usage)) + ->setDefaultSortDirection('DESC'), $this->createColumn('hardware_memorymb', $this->translate('Memory'), 'vm.hardware_memorymb') - ->setRenderer(function ($row) { - return Format::mBytes($row->hardware_memorymb); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mBytes($row->hardware_memorymb)) + ->setDefaultSortDirection('DESC'), $this->createColumn('guest_memory_usage_mb', $this->translate('Active Memory'), 'vqs.guest_memory_usage_mb') - ->setRenderer(function ($row) { - return Format::mBytes($row->guest_memory_usage_mb); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mBytes($row->guest_memory_usage_mb)) + ->setDefaultSortDirection('DESC'), $this->createColumn('host_memory_usage_mb', $this->translate('Host Memory'), 'vqs.host_memory_usage_mb') - ->setRenderer(function ($row) { - return Format::mBytes($row->host_memory_usage_mb); - })->setSortExpression('vqs.host_memory_usage_mb') + ->setRenderer(fn($row) => Format::mBytes($row->host_memory_usage_mb)) + ->setSortExpression('vqs.host_memory_usage_mb') ->setDefaultSortDirection('DESC'), $this->createColumn('ballooned_memory_mb', $this->translate('Balloon'), 'vqs.ballooned_memory_mb') - ->setRenderer(function ($row) { - return Format::mBytes($row->ballooned_memory_mb); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::mBytes($row->ballooned_memory_mb)) + ->setDefaultSortDirection('DESC'), $this->createColumn('memory_usage', $this->translate('Memory Usage'), $memoryColumns) ->setRenderer($memoryRenderer) @@ -200,33 +170,23 @@ protected function initialize() ->setDefaultSortDirection('DESC'), $this->createColumn('disk_capacity', $this->translate('Disks'), 'vmd.disk_capacity') - ->setRenderer(function ($row) { - return Format::bytes($row->disk_capacity ?: 0); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::bytes($row->disk_capacity ?: 0)) + ->setDefaultSortDirection('DESC'), $this->createColumn('datastore_capacity', $this->translate('Datastore'), 'vdu.datastore_capacity') - ->setRenderer(function ($row) { - return Format::bytes($row->datastore_capacity ?: 0); - })->setDefaultSortDirection('DESC'), + ->setRenderer(fn($row) => Format::bytes($row->datastore_capacity ?: 0)) + ->setDefaultSortDirection('DESC'), $this->createColumn('datastore_usage', $this->translate('DS Usage'), 'vdu.datastore_usage') - ->setRenderer(function ($row) { - return Format::bytes($row->datastore_usage ?: 0); - })->setDefaultSortDirection('DESC'), - - $this->createColumn('uptime', $this->translate('Uptime'), [ - 'uptime' => 'vqs.uptime', - ])->setRenderer(function ($row) { - if ($row->uptime === null) { - return null; - } + ->setRenderer(fn($row) => Format::bytes($row->datastore_usage ?: 0)) + ->setDefaultSortDirection('DESC'), - return DateFormatter::formatDuration($row->uptime); - }), + $this->createColumn('uptime', $this->translate('Uptime'), ['uptime' => 'vqs.uptime']) + ->setRenderer(fn($row) => $row->uptime === null ? null : DateFormatter::formatDuration($row->uptime)) /* TODO: Not yet $this->createColumn('ifTraffic', $this->translate('NIC Usage'), [ - 'moref' => 'o.moref', + 'moref' => 'o.moref' ])->setRenderer(function ($row) { return $this->renderInterface($row->moref, 4000); }), @@ -236,7 +196,7 @@ protected function initialize() // $this->addPerfColumns(); } - protected function renderInterface($moref, $hardwareKey) + protected function renderInterface(string $moref, string $hardwareKey): Img { $width = 160; $height = 30; @@ -244,77 +204,74 @@ protected function renderInterface($moref, $hardwareKey) $end = floor((time() - $rand) / 300) * 300; $start = $end - $rand; $params = [ - 'file' => sprintf('%s/iface%s.rrd', $moref, $hardwareKey), - 'height' => $height, - 'width' => $width, - 'rnd' => floor(time() / 20), - 'format' => 'png', - 'start' => $start, - 'end' => $end, + 'file' => sprintf('%s/iface%s.rrd', $moref, $hardwareKey), + 'height' => $height, + 'width' => $width, + 'rnd' => floor(time() / 20), + 'format' => 'png', + 'start' => $start, + 'end' => $end ]; $attrs = [ 'height' => $height, - 'width' => $width, + 'width' => $width //'align' => 'right', // 'style' => 'border-bottom: 1px solid rgba(0, 0, 0, 0.3); border-left: 1px solid rgba(0, 0, 0, 0.3);' ]; - return Img::create('rrd/img', $params + [ - 'template' => 'vSphereDB-vmIfTraffic', - ], $attrs); + return Img::create('rrd/img', $params + ['template' => 'vSphereDB-vmIfTraffic'], $attrs); } - protected function addPerfColumns() + protected function addPerfColumns(): void { $perf = new DelayedPerfdataRenderer($this->db()); $this->addAvailableColumns([ $perf->getDiskColumn()->setDefaultSortDirection('DESC'), $perf->getNetColumn()->setDefaultSortDirection('DESC'), $perf->getCurrentNetColumn()->setDefaultSortDirection('DESC'), - $perf->getCurrentDiskColumn()->setDefaultSortDirection('DESC'), + $perf->getCurrentDiskColumn()->setDefaultSortDirection('DESC') ]); } - public function getDefaultColumnNames() + public function getDefaultColumnNames(): array { return [ 'object_name', 'cpu_usage', - 'memory_usage', + 'memory_usage' ]; } - protected function getDefaultSortColumns() + protected function getDefaultSortColumns(): array { return ['object_name']; } - protected function createObjectNameColumn() + protected function createObjectNameColumn(): SimpleColumn { return $this->createColumn('object_name', $this->translate('Name'), [ 'object_name' => 'o.object_name', 'overall_status' => 'o.overall_status', 'runtime_power_state' => 'vm.runtime_power_state', 'template' => 'vm.template', - 'uuid' => 'o.uuid', - ])->setRenderer(function ($row) { - if (in_array('overall_status', $this->getChosenColumnNames())) { - $result = []; - } else { - $statusRenderer = $this->overallStatusRenderer(); - $result = [$statusRenderer($row)]; - } - $name = Anonymizer::anonymizeString($row->object_name); - if ($row->template === 'y') { - $name = [$name, Html::tag('i', ' (' . $this->translate('Template') . ')')]; - } - if ($this->baseUrl === null) { - $result[] = $name; - } else { - $result[] = Link::create($name, $this->baseUrl, ['uuid' => Uuid::fromBytes($row->uuid)->toString()]); - } + 'uuid' => 'o.uuid' + ]) + ->setRenderer(function ($row) { + if (in_array('overall_status', $this->getChosenColumnNames())) { + $result = []; + } else { + $statusRenderer = $this->overallStatusRenderer(); + $result = [$statusRenderer($row)]; + } + $name = Anonymizer::anonymizeString($row->object_name); + if ($row->template === 'y') { + $name = [$name, Html::tag('i', ' (' . $this->translate('Template') . ')')]; + } + $result[] = $this->baseUrl === null + ? $name + : Link::create($name, $this->baseUrl, ['uuid' => Uuid::fromBytes($row->uuid)->toString()]); - return $result; - }); + return $result; + }); } } diff --git a/library/Vspheredb/Web/Table/PerfDataConsumerTable.php b/library/Vspheredb/Web/Table/PerfDataConsumerTable.php index 8e367f49..2064f5ac 100644 --- a/library/Vspheredb/Web/Table/PerfDataConsumerTable.php +++ b/library/Vspheredb/Web/Table/PerfDataConsumerTable.php @@ -3,43 +3,44 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Link; +use gipfl\ZfDb\Select; use Ramsey\Uuid\Uuid; +use Zend_Db_Select; class PerfDataConsumerTable extends BaseTable { - protected $keyColumn = 'uuid'; + protected string $keyColumn = 'uuid'; protected $defaultAttributes = [ 'class' => ['common-table', 'table-row-selectable'], - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ (new SimpleColumn('name', $this->translate('Name'), [ 'uuid' => 'pc.uuid', - 'name' => 'pc.name', - ]))->setRenderer(function ($row) { - return Link::create($row->name, 'vspheredb/perfdata/consumer', [ - 'uuid' => Uuid::fromBytes($row->uuid) - ], [ - 'data-base-target' => '_next' - ]); - }), + 'name' => 'pc.name' + ])) + ->setRenderer(fn($row) => Link::create( + $row->name, + 'vspheredb/perfdata/consumer', + ['uuid' => Uuid::fromBytes($row->uuid)], + ['data-base-target' => '_next'] + )), + (new SimpleColumn('implementation', $this->translate('Implementation'), [ - 'implementation' => 'pc.implementation', - ]))->setRenderer(function ($row) { - return $row->implementation; - }), + 'implementation' => 'pc.implementation' + ])) + ->setRenderer(fn($row) => $row->implementation) ]); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - ['pc' => 'perfdata_consumer'], - $this->getRequiredDbColumns() - )->order('name'); + return $this->db()->select() + ->from(['pc' => 'perfdata_consumer'], $this->getRequiredDbColumns()) + ->order('name'); } } diff --git a/library/Vspheredb/Web/Table/PerformanceCounterTable.php b/library/Vspheredb/Web/Table/PerformanceCounterTable.php index de6fe136..f557e4a0 100644 --- a/library/Vspheredb/Web/Table/PerformanceCounterTable.php +++ b/library/Vspheredb/Web/Table/PerformanceCounterTable.php @@ -3,12 +3,13 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Url; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\DbObject\VCenter; +use Zend_Db_Select; class PerformanceCounterTable extends BaseTable { - /** @var VCenter */ - protected $vCenter; + protected ?VCenter $vCenter; protected $searchColumns = [ 'counter_key', @@ -18,9 +19,9 @@ class PerformanceCounterTable extends BaseTable 'label', 'summary', 'stats_type', - 'rollup_type', + 'rollup_type' // TODO: disabled, Director breaks this right now for security reasons - // "(c.group_name || '.' || c.name)", + // "(c.group_name || '.' || c.name)" ]; public function __construct($db, ?Url $url = null, ?VCenter $vCenter = null) @@ -29,41 +30,25 @@ public function __construct($db, ?Url $url = null, ?VCenter $vCenter = null) parent::__construct($db, $url); } - protected function initialize() + protected function initialize(): void { $this->addAvailableColumns([ - $this->createColumn('key', $this->translate('Key'), [ - 'group_name', - 'name' - ])->setRenderer(function ($row) { - return sprintf( - '%s.%s', - $row->group_name, - $row->name - ); - }), - $this->createColumn('name', $this->translate('Name'), [ - 'group_name', - 'name' - ])->setRenderer(function ($row) { - return sprintf( - '%s.%s', - $row->label, - $row->summary - ); - }), + $this->createColumn('key', $this->translate('Key'), ['group_name', 'name']) + ->setRenderer(fn($row) => sprintf('%s.%s', $row->group_name, $row->name)), + + $this->createColumn('name', $this->translate('Name'), ['group_name', 'name']) + ->setRenderer(fn($row) => sprintf('%s.%s', $row->label, $row->summary)), + $this->createColumn('unit_name', $this->translate('Unit')), $this->createColumn('stats_type', $this->translate('Stats')), $this->createColumn('rollup_type', $this->translate('Rollup')), - $this->createColumn('counter_key', $this->translate('ID')), + $this->createColumn('counter_key', $this->translate('ID')) ]); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['c' => 'performance_counter'] - ); + $query = $this->db()->select()->from(['c' => 'performance_counter']); // ->order('group_name')->order('name')->order('unit_name'); if ($this->vCenter !== null) { diff --git a/library/Vspheredb/Web/Table/SimpleColumn.php b/library/Vspheredb/Web/Table/SimpleColumn.php index 1f46ed6d..ba0f9046 100644 --- a/library/Vspheredb/Web/Table/SimpleColumn.php +++ b/library/Vspheredb/Web/Table/SimpleColumn.php @@ -4,7 +4,7 @@ class SimpleColumn extends TableColumn { - public function __construct($alias, $title = null, $column = null) + public function __construct(string $alias, ?string $title = null, string|array|null $column = null) { $this->setAlias($alias); $this->setTitle($title ?: $alias); diff --git a/library/Vspheredb/Web/Table/TableColumn.php b/library/Vspheredb/Web/Table/TableColumn.php index d1fc181f..8e33e289 100644 --- a/library/Vspheredb/Web/Table/TableColumn.php +++ b/library/Vspheredb/Web/Table/TableColumn.php @@ -2,142 +2,144 @@ namespace Icinga\Module\Vspheredb\Web\Table; +use Closure; use ipl\Html\Html; +use ipl\Html\HtmlDocument; +use ipl\Html\ValidHtml; abstract class TableColumn { - /** @var string */ - private $alias; + private ?string $alias = null; - /** @var string */ - private $column; + private array|string|null $column = null; - /** @var string */ - private $title; + private ?string $title = null; - /** @var callable */ - private $renderer; + private ?Closure $renderer = null; - /** @var string|null */ - private $sortExpression; + private array|string|null $sortExpression = null; - /** @var string */ - private $defaultSortDirection = 'ASC'; + private string $defaultSortDirection = 'ASC'; - public function getRequiredDbColumns() + public function getRequiredDbColumns(): array { $column = $this->getColumn(); if (is_array($column)) { return $column; - } else { - return [$this->getAlias() => $column]; } + + return [$this->getAlias() => $column]; } - public function getMainColumnExpression() + public function getMainColumnExpression(): array|string|null { $column = $this->getColumn(); if (is_array($column)) { return array_shift($column); - } else { - return $column; } + + return $column; } - public function setRenderer($callback) + public function setRenderer(callable $callback): static { - $this->renderer = $callback; + $this->renderer = $callback(...); return $this; } /** - * @return string + * @return ?string */ - public function getAlias() + public function getAlias(): ?string { return $this->alias; } /** * @param string $alias + * * @return $this */ - public function setAlias($alias) + public function setAlias(string $alias): static { $this->alias = $alias; + return $this; } /** - * @return string + * @return array|string|null */ - public function getColumn() + public function getColumn(): array|string|null { return $this->column; } /** - * @param string $column + * @param array|string $column + * * @return TableColumn */ - public function setColumn($column) + public function setColumn(array|string $column): static { $this->column = $column; return $this; } /** - * @return string + * @return ?string */ - public function getTitle() + public function getTitle(): ?string { return $this->title; } /** * @param string $title + * * @return $this */ - public function setTitle($title) + public function setTitle(string $title): static { $this->title = $title; + return $this; } - public function renderRow($row) + /** + * @param $row + * + * @return ValidHtml|HtmlDocument|mixed + */ + public function renderRow($row): mixed { - if ($this->renderer === null) { - return Html::wantHtml($row->{$this->getAlias()}); - } else { - $func = $this->renderer; - - return $func($row); - } + return $this->renderer === null ? Html::wantHtml($row->{$this->getAlias()}) : ($this->renderer)($row); } /** - * @return null|string + * @return array|string|null */ - public function getSortExpression() + public function getSortExpression(): array|string|null { if (null === $this->sortExpression) { $column = $this->getColumn(); if (is_array($column)) { return current($column); - } else { - return $column; } - } else { - return $this->sortExpression; + + return $column; } + + return $this->sortExpression; } /** - * @param null|string|array $sortExpression + * @param array|string|null $sortExpression + * * @return $this */ - public function setSortExpression($sortExpression) + public function setSortExpression(array|string|null $sortExpression): static { $this->sortExpression = $sortExpression; @@ -147,18 +149,20 @@ public function setSortExpression($sortExpression) /** * @return string */ - public function getDefaultSortDirection() + public function getDefaultSortDirection(): string { return $this->defaultSortDirection; } /** * @param string $defaultSortDirection + * * @return $this */ - public function setDefaultSortDirection($defaultSortDirection) + public function setDefaultSortDirection(string $defaultSortDirection): static { $this->defaultSortDirection = $defaultSortDirection; + return $this; } } diff --git a/library/Vspheredb/Web/Table/TableWithParentFilter.php b/library/Vspheredb/Web/Table/TableWithParentFilter.php index 2b80809b..dae3b226 100644 --- a/library/Vspheredb/Web/Table/TableWithParentFilter.php +++ b/library/Vspheredb/Web/Table/TableWithParentFilter.php @@ -4,5 +4,5 @@ interface TableWithParentFilter { - public function filterParentUuids(array $uuids); + public function filterParentUuids(array $uuids): static; } diff --git a/library/Vspheredb/Web/Table/TableWithVCenterFilter.php b/library/Vspheredb/Web/Table/TableWithVCenterFilter.php index 65acbace..b752c87d 100644 --- a/library/Vspheredb/Web/Table/TableWithVCenterFilter.php +++ b/library/Vspheredb/Web/Table/TableWithVCenterFilter.php @@ -6,6 +6,7 @@ interface TableWithVCenterFilter { - public function filterVCenter(VCenter $vCenter); - public function filterVCenterUuids(array $uuids); + public function filterVCenter(VCenter $vCenter): static; + + public function filterVCenterUuids(array $uuids): static; } diff --git a/library/Vspheredb/Web/Table/TopPerfTable.php b/library/Vspheredb/Web/Table/TopPerfTable.php index ea293282..312fa04a 100644 --- a/library/Vspheredb/Web/Table/TopPerfTable.php +++ b/library/Vspheredb/Web/Table/TopPerfTable.php @@ -4,47 +4,45 @@ use gipfl\IcingaWeb2\Link; use Icinga\Module\Vspheredb\Util; +use ipl\Html\Attributes; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\Html\Table; class TopPerfTable extends Table { protected $defaultAttributes = [ 'class' => 'common-table table-row-selectable', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - public function __construct($title, $rows, $format, $link) + public function __construct(string $title, ?array $rows, ?string $format, string $link) { $this->getHeader()->add(Table::tr([ Table::th($title), - Table::th('5x5min')->addAttributes(['class' => 'sparkline-header']), - Table::th('Last 5min')->addAttributes(['class' => 'last-5min-header']) + Table::th('5x5min')->addAttributes(Attributes::create(['class' => 'sparkline-header'])), + Table::th('Last 5min')->addAttributes(Attributes::create(['class' => 'last-5min-header'])) ])); foreach ($rows as $row) { $this->getBody()->add(Table::row([ $this->$link($row), $this->makeSparkLine($row), - $format ? $this->$format($row->value_last) : $row->value_last, + $format ? $this->$format($row->value_last) : $row->value_last ])); } } - protected function createVmLink($row) + protected function createVmLink(object $row): Link { $name = $row->object_name; if (property_exists($row, 'instance') && strlen($row->instance)) { $name .= ': ' . $row->instance; } - return Link::create( - $name, - 'vspheredb/vm', - Util::uuidParams($row->object_uuid) - ); + return Link::create($name, 'vspheredb/vm', Util::uuidParams($row->object_uuid)); } - protected function createTopForParentLink($row) + protected function createTopForParentLink(object $row): Link { return Link::create( $row->object_name, @@ -53,35 +51,33 @@ protected function createTopForParentLink($row) ); } - protected function formatMicroSeconds($num) + protected function formatMicroSeconds(int $num): string { if ($num > 500) { return sprintf('%0.2Fms', $num / 1000); - } else { - return sprintf('%dµs', $num); } + + return sprintf('%dµs', $num); } - protected function formatKiloBytesPerSecond($num) + protected function formatKiloBytesPerSecond(int $num): string { $num *= 8; - if ($num > 500000) { - return sprintf('%0.2F Gbit/s', $num / 1024 / 1024); - } elseif ($num > 500) { - return sprintf('%0.2F Mbit/s', $num / 1024); - } else { - return sprintf('%0.2F Kbit/s', $num); - } + return match (true) { + $num > 500000 => sprintf('%0.2F Gbit/s', $num / 1024 / 1024), + $num > 500 => sprintf('%0.2F Mbit/s', $num / 1024), + default => sprintf('%0.2F Kbit/s', $num) + }; } - protected function makeSparkLine($row) + protected function makeSparkLine($row): HtmlElement { $values = [ $row->value_minus4, $row->value_minus3, $row->value_minus2, $row->value_minus1, - $row->value_last, + $row->value_last ]; return Html::tag('span', [ diff --git a/library/Vspheredb/Web/Table/UuidLinkHelper.php b/library/Vspheredb/Web/Table/UuidLinkHelper.php index 1110bb0c..9bb6717f 100644 --- a/library/Vspheredb/Web/Table/UuidLinkHelper.php +++ b/library/Vspheredb/Web/Table/UuidLinkHelper.php @@ -8,9 +8,9 @@ trait UuidLinkHelper { - protected $requiredUuids = []; + protected array $requiredUuids = []; - protected $fetchedUuids; + protected ?array $fetchedUuids = null; /** * @param ?string $uuid @@ -42,32 +42,26 @@ public function linkToUuid(?string $uuid): DeferredText ); }); - return $result->setEscaped(true); + return $result->setEscaped(); } - protected function getUuidBaseUrl($uuid) + protected function getUuidBaseUrl($uuid): ?string { - $type = $this->getUuidProperty($uuid, 'object_type'); - - switch ($type) { - case 'HostSystem': - return 'vspheredb/host'; - case 'VirtualMachine': - return 'vspheredb/vm'; - case 'Datastore': - return 'vspheredb/datastore'; - default: - return null; - } + return match ($this->getUuidProperty($uuid, 'object_type')) { + 'HostSystem' => 'vspheredb/host', + 'VirtualMachine' => 'vspheredb/vm', + 'Datastore' => 'vspheredb/datastore', + default => null + }; } /** * @param ?string $uuid - * @param $property + * @param string $property * * @return string */ - protected function getUuidProperty(?string $uuid, $property): string + protected function getUuidProperty(?string $uuid, string $property): string { if ($uuid === null) { return '[NULL]'; @@ -79,21 +73,22 @@ protected function getUuidProperty(?string $uuid, $property): string if (array_key_exists($uuid, $this->fetchedUuids)) { return $this->fetchedUuids[$uuid]->$property; - } else { - return '[UNKNOWN]' . $uuid; } + + return '[UNKNOWN]' . $uuid; } - protected function fetchUuidObjectDetails() + protected function fetchUuidObjectDetails(): void { - if (method_exists($this, 'db')) { - /** @var \Zend_Db_Adapter_Abstract $db */ - $db = $this->db(); - } else { + if (! method_exists($this, 'db')) { $this->fetchedUuids = []; return; } + + /** @var Zend_Db_Adapter_Abstract $db */ + $db = $this->db(); + if (empty($this->requiredUuids)) { $this->fetchedUuids = []; diff --git a/library/Vspheredb/Web/Table/VmDatastoresTable.php b/library/Vspheredb/Web/Table/VmDatastoresTable.php index 7f563603..0e04199d 100644 --- a/library/Vspheredb/Web/Table/VmDatastoresTable.php +++ b/library/Vspheredb/Web/Table/VmDatastoresTable.php @@ -4,6 +4,7 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; @@ -12,23 +13,20 @@ use Icinga\Module\Vspheredb\Web\Widget\OverallStatusRenderer; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; use Icinga\Util\Format; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class VmDatastoresTable extends ZfQueryBasedTable { - protected $searchColumns = [ - 'object_name', - ]; + protected $searchColumns = ['object_name']; protected $parentIds; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var string */ - protected $uuid; + protected ?string $uuid = null; - /** @var OverallStatusRenderer */ - protected $renderStatus; + protected OverallStatusRenderer $renderStatus; public function __construct(VirtualMachine $vm) { @@ -39,7 +37,7 @@ public function __construct(VirtualMachine $vm) $this->renderStatus = new OverallStatusRenderer(); } - protected function setVm(VirtualMachine $vm) + protected function setVm(VirtualMachine $vm): static { $this->vm = $vm; $this->uuid = $vm->get('uuid'); @@ -47,72 +45,62 @@ protected function setVm(VirtualMachine $vm) return $this; } - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): array { return [ $this->translate('Status'), $this->translate('Datastore'), $this->translate('Size'), $this->translate('Usage'), - $this->translate('On Datastore'), + $this->translate('On Datastore') ]; } - public function renderRow($row) + public function renderRow($row): HtmlElement { $size = $row->committed + $row->uncommitted; $caption = Link::create( $row->object_name, 'vspheredb/datastore', Util::uuidParams($row->uuid), - ['title' => sprintf( - $this->translate('Datastore: %s'), - $row->object_name - )] + ['title' => sprintf($this->translate('Datastore: %s'), $row->object_name)] ); /** @var Db $connection */ $connection = $this->connection(); $datastore = Datastore::load($row->uuid, $connection); - $usage = new DatastoreUsage($datastore); - $usage->setBaseUrl('vspheredb/datastore'); - $usage->setCapacity($size); + $usage = (new DatastoreUsage($datastore)) + ->setBaseUrl('vspheredb/datastore') + ->setCapacity($size) + ->addDiskFromDbRow($row); $usage->getAttributes()->add('class', 'compact'); - $usage->addDiskFromDbRow($row); - $dsUsage = new DatastoreUsage($datastore); - $dsUsage->setBaseUrl('vspheredb/datastore'); + $dsUsage = (new DatastoreUsage($datastore)) + ->setBaseUrl('vspheredb/datastore') + ->addDiskFromDbRow($row); $dsUsage->getAttributes()->add('class', 'compact'); - $dsUsage->addDiskFromDbRow($row); $renderStatus = $this->renderStatus; - $tr = $this::tr([ + + return $this::tr([ $this::td($renderStatus($row->overall_status)), $this::td($caption, ['class' => 'vm-datastore-caption']), $this::td(Format::bytes($size), ['class' => 'vm-datastore-size']), $this::td($usage, ['class' => 'vm-datastore-usage']), - $this::td($dsUsage, ['class' => 'vm-datastore-on-datastore']), + $this::td($dsUsage, ['class' => 'vm-datastore-on-datastore']) ]); - - return $tr; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - [ + return $this->db()->select() + ->from(['o' => 'object'], [ 'uuid' => 'o.uuid', 'overall_status' => 'o.overall_status', 'object_name' => 'o.object_name', 'committed' => 'vdu.committed', - 'uncommitted' => 'vdu.uncommitted', - ] - )->join( - ['vdu' => 'vm_datastore_usage'], - 'vdu.datastore_uuid = o.uuid', - [] - )->where('vdu.vm_uuid = ?', $this->uuid)->order('object_name ASC'); - - return $query; + 'uncommitted' => 'vdu.uncommitted' + ]) + ->join(['vdu' => 'vm_datastore_usage'], 'vdu.datastore_uuid = o.uuid', []) + ->where('vdu.vm_uuid = ?', $this->uuid)->order('object_name ASC'); } } diff --git a/library/Vspheredb/Web/Table/VmDiskUsageTable.php b/library/Vspheredb/Web/Table/VmDiskUsageTable.php index 993a24d2..d834d5a7 100644 --- a/library/Vspheredb/Web/Table/VmDiskUsageTable.php +++ b/library/Vspheredb/Web/Table/VmDiskUsageTable.php @@ -4,32 +4,34 @@ use gipfl\IcingaWeb2\Img; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\Web\Widget\SimpleUsageBar; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; use Icinga\Util\Format; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class VmDiskUsageTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => ['vm-disk-usage-table', 'common-table', 'table-row-selectable'], - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - protected $totalSize = 0; + protected int $totalSize = 0; - protected $totalFree = 0; + protected int $totalFree = 0; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var string */ - protected $uuid; + protected ?string $uuid = null; - private $root; + private object $root; - private $withHistory = false; + private bool $withHistory = false; public function __construct(VirtualMachine $vm) { @@ -37,7 +39,7 @@ public function __construct(VirtualMachine $vm) $this->setVm($vm); } - protected function setVm(VirtualMachine $vm) + protected function setVm(VirtualMachine $vm): static { $this->vm = $vm; $this->uuid = $vm->get('uuid'); @@ -45,11 +47,12 @@ protected function setVm(VirtualMachine $vm) return $this; } - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): ?array { if (count($this) === 0) { $this->prepend($this->translate('No guest disk found. Please check guest utilities')); $this->prepend(new SubTitle($this->translate('Guest Disk Usage'), 'chart-pie')); + return null; } @@ -59,16 +62,18 @@ public function getColumnsToBeRendered() $this->translate('Disk'), $this->translate('Size'), $this->translate('Free space'), - $this->translate('Usage'), + $this->translate('Usage') ]; } /** * @param $row - * @return \ipl\Html\HtmlElement - * @throws \Icinga\Exception\NotFoundError + * + * @return HtmlElement + * + * @throws NotFoundError */ - public function renderRow($row) + public function renderRow($row): HtmlElement { $caption = $row->disk_path; @@ -76,13 +81,10 @@ public function renderRow($row) $this->root = $row; } - $free = Format::bytes($row->free_space) - . sprintf(' (%0.3f%%)', ($row->free_space / $row->capacity) * 100); + $free = Format::bytes($row->free_space) . sprintf(' (%0.3f%%)', ($row->free_space / $row->capacity) * 100); $tr = $this::tr([ - $this::td($caption, [ - 'title' => $caption - ]), + $this::td($caption, ['title' => $caption]), $this::td(Format::bytes($row->capacity), ['class' => 'vm-disk-usage-capacity']), $this::td($free, ['class' => 'vm-disk-usage-free']), $this::td($this->makeDisk($row), ['class' => 'vm-disk-usage-usage']) @@ -111,7 +113,7 @@ public function renderRow($row) 'width' => 480, 'start' => $start, 'end' => $end, - 'template' => 'vm_disk', + 'template' => 'vm_disk' ]), [ 'colspan' => 4, @@ -123,7 +125,7 @@ public function renderRow($row) return $tr; } - protected function fetchRows() + protected function fetchRows(): void { parent::fetchRows(); if (count($this) === 0) { @@ -135,34 +137,34 @@ protected function fetchRows() $this::th(Html::tag('strong', null, $this->translate('Total'))), $this::th(Format::bytes($this->totalSize), ['class' => 'vm-disk-usage-capacity']), $this::th($free, ['class' => 'vm-disk-usage-free']), - $this::th($this->makeDisk((object) [ - 'disk_path' => $this->translate('Total'), - 'capacity' => $this->totalSize, - 'free_space' => $this->totalFree - ]), ['class' => 'vm-disk-usage-usage']) + $this::th( + $this->makeDisk((object) [ + 'disk_path' => $this->translate('Total'), + 'capacity' => $this->totalSize, + 'free_space' => $this->totalFree + ]), + ['class' => 'vm-disk-usage-usage'] + ) ])); } - public function generateFooter() + public function generateFooter(): HtmlElement { return Html::tag('tfoot'); } - protected function makeDisk($disk) + protected function makeDisk(object $disk): SimpleUsageBar { $used = $disk->capacity - $disk->free_space; return new SimpleUsageBar($used, $disk->capacity, $disk->disk_path); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - return $this->db()->select()->from( - 'vm_disk_usage', - ['disk_path', 'capacity', 'free_space'] - )->where( - 'vm_uuid = ?', - $this->uuid - )->order('disk_path'); + return $this->db()->select() + ->from('vm_disk_usage', ['disk_path', 'capacity', 'free_space']) + ->where('vm_uuid = ?', $this->uuid) + ->order('disk_path'); } } diff --git a/library/Vspheredb/Web/Table/VmDisksTable.php b/library/Vspheredb/Web/Table/VmDisksTable.php index 834c4488..c84bac4f 100644 --- a/library/Vspheredb/Web/Table/VmDisksTable.php +++ b/library/Vspheredb/Web/Table/VmDisksTable.php @@ -3,34 +3,32 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\PerformanceData\IcingaRrd\RrdImg; use Icinga\Module\Vspheredb\Web\Widget\OverallStatusRenderer; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; use Icinga\Util\Format; +use ipl\Html\FormattedString; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class VmDisksTable extends ZfQueryBasedTable { - protected $searchColumns = [ - 'object_name', - ]; + protected $searchColumns = ['object_name']; protected $parentIds; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var string */ - protected $uuid; + protected ?string $uuid = null; - /** @var string */ - protected $moref; + protected ?string $moref = null; - /** @var OverallStatusRenderer */ - protected $renderStatus; + protected OverallStatusRenderer $renderStatus; - protected $withPerfImages = false; + protected bool $withPerfImages = false; public function __construct(VirtualMachine $vm) { @@ -40,7 +38,7 @@ public function __construct(VirtualMachine $vm) $this->setVm($vm); } - protected function setVm(VirtualMachine $vm) + protected function setVm(VirtualMachine $vm): static { $this->vm = $vm; $this->uuid = $vm->get('uuid'); @@ -49,7 +47,7 @@ protected function setVm(VirtualMachine $vm) return $this; } - public function renderRow($row) + public function renderRow($row): HtmlElement { $device = sprintf( '%s%d:%d', @@ -68,18 +66,16 @@ public function renderRow($row) Html::tag('br'), $device, Html::tag('br'), - Format::bytes($row->capacity), + Format::bytes($row->capacity) ], ['class' => 'vm-disks-with-perf-image']), $this->prepareImgColumn($device) ]); - } else { - return $this->row([ - $this->formatSimple($row, $device) - ]); } + + return $this->row([$this->formatSimple($row, $device)]); } - protected function formatSimple($row, $device) + protected function formatSimple(object $row, string $device): FormattedString { return Html::sprintf( '%s (%s): %s', @@ -89,35 +85,37 @@ protected function formatSimple($row, $device) ); } - protected function prepareImgColumn($device) + protected function prepareImgColumn($device): ?HtmlElement { if ($this->withPerfImages) { return $this::td([ RrdImg::vmDiskSeeks($this->moref, $device), RrdImg::vmDiskReadWrites($this->moref, $device), - RrdImg::vmDiskTotalLatency($this->moref, $device), + RrdImg::vmDiskTotalLatency($this->moref, $device) ]); - } else { - return null; } + + return null; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $uuid = $this->vm->get('uuid'); - $query = $this->db()->select()->from(['vmd' => 'vm_disk'], [ - 'controller_label' => 'vmhc.label', - 'hardware_label' => 'vmhw.label', - 'hardware_key' => 'vmhw.hardware_key', - 'hardware_bus_number' => 'vmhc.bus_number', - 'hardware_unit_nmber' => 'vmhw.unit_number', - 'capacity' => 'vmd.capacity', - ]) - ->join(['vmhw' => 'vm_hardware'], 'vmd.vm_uuid = vmhw.vm_uuid AND vmd.hardware_key = vmhw.hardware_key', []) - ->join(['vmhc' => 'vm_hardware'], 'vmhw.vm_uuid = vmhc.vm_uuid AND vmhw.controller_key = vmhc.hardware_key', []) - ->where('vmd.vm_uuid = ?', $uuid) - ->order('hardware_label'); - - return $query; + return $this->db()->select() + ->from(['vmd' => 'vm_disk'], [ + 'controller_label' => 'vmhc.label', + 'hardware_label' => 'vmhw.label', + 'hardware_key' => 'vmhw.hardware_key', + 'hardware_bus_number' => 'vmhc.bus_number', + 'hardware_unit_nmber' => 'vmhw.unit_number', + 'capacity' => 'vmd.capacity' + ]) + ->join(['vmhw' => 'vm_hardware'], 'vmd.vm_uuid = vmhw.vm_uuid AND vmd.hardware_key = vmhw.hardware_key', []) + ->join( + ['vmhc' => 'vm_hardware'], + 'vmhw.vm_uuid = vmhc.vm_uuid AND vmhw.controller_key = vmhc.hardware_key', + [] + ) + ->where('vmd.vm_uuid = ?', $this->vm->get('uuid')) + ->order('hardware_label'); } } diff --git a/library/Vspheredb/Web/Table/VmNetworkAdapterTable.php b/library/Vspheredb/Web/Table/VmNetworkAdapterTable.php index c72cb674..095ccab0 100644 --- a/library/Vspheredb/Web/Table/VmNetworkAdapterTable.php +++ b/library/Vspheredb/Web/Table/VmNetworkAdapterTable.php @@ -2,33 +2,32 @@ namespace Icinga\Module\Vspheredb\Web\Table; -use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\PerformanceData\IcingaRrd\RrdImg; -use Icinga\Module\Vspheredb\Web\Widget\GrafanaVmPanel; use Icinga\Module\Vspheredb\Web\Widget\MacAddress; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; +use ipl\Html\FormattedString; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use stdClass; +use Zend_Db_Select; class VmNetworkAdapterTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => 'common-table', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var string */ - protected $moref; + protected ?string $moref; - protected $withPerfImages = false; - /** - * @var array - */ - protected $ipAddresses; + protected bool $withPerfImages = false; + + protected stdClass $ipAddresses; public function __construct(VirtualMachine $vm) { @@ -39,45 +38,38 @@ public function __construct(VirtualMachine $vm) parent::__construct($vm->getConnection()); } - public function renderRow($row) + public function renderRow($row): HtmlElement { // $this->add($this::row([ // new GrafanaVmPanel($this->vm->object(), [1, 3], $row->label, 'All') // ])); if ($this->withPerfImages) { - return $this::row([ - $this->formatMultiLine($row), - $this->prepareRowImages($row), - ]); - } else { - return $this::row([$this->formatSimple($row)]); + return $this::row([$this->formatMultiLine($row), $this->prepareRowImages($row)]); } + + return $this::row([$this->formatSimple($row)]); } - protected function linkToPortGroup($row) + protected function linkToPortGroup($row): string|FormattedString { if ($row->port_key === null) { return ''; // TODO: explain (no portgroup -> ESXi?) } elseif ($row->portgroup_uuid === null) { - return \sprintf($this->translate('Port %s'), $row->port_key); - } else { - return Html::sprintf( - 'Port %s on %s', - $row->port_key, - $row->portgroup_name - /* // TODO: - // Link::create( - // $row->portgroup_name, - // 'vspheredb/portgroup', - // ['uuid' => Util::niceUuid($row->portgroup_uuid)], - // ['data-base-target' => '_next'] - // ) - */ - ); + return sprintf($this->translate('Port %s'), $row->port_key); } + + return Html::sprintf('Port %s on %s', $row->port_key, $row->portgroup_name); + /* // TODO: + // Link::create( + // $row->portgroup_name, + // 'vspheredb/portgroup', + // ['uuid' => Util::niceUuid($row->portgroup_uuid)], + // ['data-base-target' => '_next'] + // ) + */ } - protected function formatSimple($row) + protected function formatSimple($row): FormattedString { $ipInfo = $this->ipAddresses->{$row->hardware_key} ?? null; if ($ipInfo) { @@ -93,17 +85,11 @@ protected function formatSimple($row) $aIpInfo = []; foreach ($ipInfo->addresses as $address) { // Explicit check for isset, as WP had a workaround skipping the property - if (! isset($address->state) || $address->state === null) { - $aIpInfo[] = sprintf('%s/%s', $address->address, $address->prefixLength); - } else { - $aIpInfo[] = sprintf('%s/%s (%s)', $address->address, $address->prefixLength, $address->state); - } - } - if (empty($aIpInfo)) { - $aIpInfo = ''; - } else { - $aIpInfo = implode(', ', $aIpInfo); + $aIpInfo = ! isset($address->state) + ? sprintf('%s/%s', $address->address, $address->prefixLength) + : sprintf('%s/%s (%s)', $address->address, $address->prefixLength, $address->state); } + $aIpInfo = empty($aIpInfo) ? '' : implode(', ', $aIpInfo); } else { $mainIpInfo = ''; $aIpInfo = ''; @@ -121,7 +107,7 @@ protected function formatSimple($row) ); } - protected function formatMultiLine($row) + protected function formatMultiLine($row): array { return [ Html::tag('strong', $row->label), @@ -133,37 +119,28 @@ protected function formatMultiLine($row) ]; } - protected function prepareRowImages($row) + protected function prepareRowImages($row): array { return [ RrdImg::vmIfTraffic($this->moref, $row->hardware_key), - RrdImg::vmIfPackets($this->moref, $row->hardware_key), + RrdImg::vmIfPackets($this->moref, $row->hardware_key) ]; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['vna' => 'vm_network_adapter'], - [ + return $this->db()->select() + ->from(['vna' => 'vm_network_adapter'], [ 'vh.label', 'vna.hardware_key', 'vna.port_key', 'vna.mac_address', 'vna.address_type', 'vna.portgroup_uuid', - 'portgroup_name' => 'pgo.object_name', - ] - )->join( - ['vh' => 'vm_hardware'], - 'vh.vm_uuid = vna.vm_uuid AND vh.hardware_key = vna.hardware_key', - [] - )->joinLeft( - ['pgo' => 'object'], - 'pgo.uuid = vna.portgroup_uuid', - [] - )->where('vna.vm_uuid = ?', $this->vm->get('uuid'))->order('vh.label ASC'); - - return $query; + 'portgroup_name' => 'pgo.object_name' + ]) + ->join(['vh' => 'vm_hardware'], 'vh.vm_uuid = vna.vm_uuid AND vh.hardware_key = vna.hardware_key', []) + ->joinLeft(['pgo' => 'object'], 'pgo.uuid = vna.portgroup_uuid', []) + ->where('vna.vm_uuid = ?', $this->vm->get('uuid'))->order('vh.label ASC'); } } diff --git a/library/Vspheredb/Web/Table/VmSnapshotTable.php b/library/Vspheredb/Web/Table/VmSnapshotTable.php index 614c511e..3e08e109 100644 --- a/library/Vspheredb/Web/Table/VmSnapshotTable.php +++ b/library/Vspheredb/Web/Table/VmSnapshotTable.php @@ -3,20 +3,22 @@ namespace Icinga\Module\Vspheredb\Web\Table; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\Web\Widget\SubTitle; use ipl\Html\Html; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class VmSnapshotTable extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => ['common-table', 'day-time-table'], - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; public function __construct(VirtualMachine $vm) { @@ -24,25 +26,23 @@ public function __construct(VirtualMachine $vm) $this->setVm($vm); } - protected function setVm(VirtualMachine $vm) + protected function setVm(VirtualMachine $vm): static { $this->vm = $vm; return $this; } - protected function assemble() + protected function assemble(): void { parent::assemble(); if (count($this) === 0) { - $this->prepend( - Html::tag('p', null, $this->translate('No snapshots have been created for this VM')) - ); + $this->prepend(Html::tag('p', null, $this->translate('No snapshots have been created for this VM'))); } $this->prepend(new SubTitle($this->translate('Snapshots'), 'history')); } - public function renderRow($row) + public function renderRow($row): HtmlElement { $this->renderDayIfNew($row->ts_create / 1000); @@ -54,16 +54,11 @@ public function renderRow($row) ]); } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - 'vm_snapshot' - )->order('ts_create DESC'); - - if ($this->vm) { - $query->where('vm_uuid = ?', $this->vm->get('uuid')); - } - - return $query; + return $this->db()->select() + ->from('vm_snapshot') + ->where('vm_uuid = ?', $this->vm->get('uuid')) + ->order('ts_create DESC'); } } diff --git a/library/Vspheredb/Web/Table/VmsOnDatastoreTable.php b/library/Vspheredb/Web/Table/VmsOnDatastoreTable.php index c82be07b..1d51623e 100644 --- a/library/Vspheredb/Web/Table/VmsOnDatastoreTable.php +++ b/library/Vspheredb/Web/Table/VmsOnDatastoreTable.php @@ -5,38 +5,34 @@ use gipfl\IcingaWeb2\Icon; use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\Data\Anonymizer; use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\Util; use Icinga\Module\Vspheredb\Web\Widget\DatastoreUsage; use Icinga\Util\Format; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class VmsOnDatastoreTable extends ZfQueryBasedTable { - protected $searchColumns = [ - 'object_name', - ]; + protected $searchColumns = ['object_name']; - /** @var Datastore */ - protected $datastore; + protected ?Datastore $datastore = null; - /** @var string */ - protected $uuid; + protected ?string $uuid = null; - /** @var int */ - protected $capacity; + protected ?int $capacity = null; - /** @var int */ - protected $uncommitted; + protected ?int $uncommitted = null; - public static function create(Datastore $datastore) + public static function create(Datastore $datastore): VmsOnDatastoreTable { - $tbl = new static($datastore->getConnection()); - return $tbl->setDatastore($datastore); + return (new static($datastore->getConnection()))->setDatastore($datastore); } - protected function setDatastore(Datastore $datastore) + protected function setDatastore(Datastore $datastore): static { $this->datastore = $datastore; $this->uuid = $datastore->get('uuid'); @@ -46,17 +42,17 @@ protected function setDatastore(Datastore $datastore) return $this; } - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): array { return [ $this->translate('Virtual Machine'), $this->translate('Size'), $this->translate('Usage'), - $this->translate('On Datastore'), + $this->translate('On Datastore') ]; } - public function renderRow($row) + public function renderRow($row): HtmlElement { $row->object_name = Anonymizer::anonymizeString($row->object_name); $size = $row->committed + $row->uncommitted; @@ -64,19 +60,16 @@ public function renderRow($row) $row->object_name, 'vspheredb/vm', Util::uuidParams($row->uuid), - ['title' => sprintf( - $this->translate('Virtual Machine: %s'), - $row->object_name - )] + ['title' => sprintf($this->translate('Virtual Machine: %s'), $row->object_name)] ); - $usage = new DatastoreUsage($this->datastore); - $usage->setCapacity($size); + $usage = (new DatastoreUsage($this->datastore)) + ->setCapacity($size) + ->addDiskFromDbRow($row); $usage->getAttributes()->add('class', 'compact'); - $usage->addDiskFromDbRow($row); - $dsUsage = new DatastoreUsage($this->datastore); + $dsUsage = (new DatastoreUsage($this->datastore)) + ->addDiskFromDbRow($row); $dsUsage->getAttributes()->add('class', 'compact'); - $dsUsage->addDiskFromDbRow($row); $tr = $this::tr([ $this::td($caption, ['class' => 'vm-on-datastore-caption']), @@ -100,23 +93,17 @@ public function renderRow($row) return $tr; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { - $query = $this->db()->select()->from( - ['o' => 'object'], - [ + return $this->db()->select() + ->from(['o' => 'object'], [ 'uuid' => 'o.uuid', 'object_name' => 'o.object_name', 'committed' => 'vdu.committed', 'uncommitted' => 'vdu.uncommitted', - 'ts_updated' => 'vdu.ts_updated', - ] - )->join( - ['vdu' => 'vm_datastore_usage'], - 'vdu.vm_uuid = o.uuid', - [] - )->where('vdu.datastore_uuid = ?', $this->uuid)->order('object_name ASC'); - - return $query; + 'ts_updated' => 'vdu.ts_updated' + ]) + ->join(['vdu' => 'vm_datastore_usage'], 'vdu.vm_uuid = o.uuid', []) + ->where('vdu.datastore_uuid = ?', $this->uuid)->order('object_name ASC'); } } diff --git a/library/Vspheredb/Web/Table/VmsWithDuplicateProperty.php b/library/Vspheredb/Web/Table/VmsWithDuplicateProperty.php index 180241f9..bb783154 100644 --- a/library/Vspheredb/Web/Table/VmsWithDuplicateProperty.php +++ b/library/Vspheredb/Web/Table/VmsWithDuplicateProperty.php @@ -4,44 +4,38 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use gipfl\ZfDb\Select; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Util; +use ipl\Html\HtmlElement; +use Zend_Db_Select; class VmsWithDuplicateProperty extends ZfQueryBasedTable { protected $defaultAttributes = [ 'class' => ['common-table', 'table-row-selectable'], - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; - protected $searchColumns = [ - 'object_name', - ]; + protected $searchColumns = ['object_name']; - protected $property; + protected ?string $property = null; - protected $propertyTitle; + protected ?string $propertyTitle = null; - protected $lastValue; + protected ?string $lastValue = null; - public static function create(Db $db, $property, $title) + public static function create(Db $db, string $property, string $title): static { - $table = new static($db); - $table->property = $property; - $table->propertyTitle = $title; - - return $table; + return (new static($db))->setProperty($property, $title); } - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): array { - return [ - $this->propertyTitle, - $this->translate('Name'), - ]; + return [$this->propertyTitle, $this->translate('Name')]; } - public function getColor() + public function getColor(): string { if (count($this) > 0) { return 'yellow'; @@ -50,7 +44,7 @@ public function getColor() return 'green'; } - public function setProperty($name, $title) + public function setProperty(string $name, string $title): static { $this->property = $name; $this->propertyTitle = $title; @@ -58,26 +52,16 @@ public function setProperty($name, $title) return $this; } - public function renderRow($row) + public function renderRow($row): HtmlElement { - $caption = Link::create( - $row->object_name, - 'vspheredb/vm', - Util::uuidParams($row->uuid) - ); + $caption = Link::create($row->object_name, 'vspheredb/vm', Util::uuidParams($row->uuid)); $value = $row->{$this->property}; if ($value === $this->lastValue) { - $tr = $this::row([ - '', - $caption, - ]); + $tr = $this::row(['', $caption]); } else { - $tr = $this::row([ - $value, - $caption, - ]); + $tr = $this::row([$value, $caption]); $this->lastValue = $value; } $tr->getAttributes()->add('class', [$row->runtime_power_state, $row->overall_status]); @@ -85,34 +69,28 @@ public function renderRow($row) return $tr; } - public function prepareQuery() + public function prepareQuery(): Select|Zend_Db_Select { $db = $this->db(); $property = $this->property; $this->searchColumns[] = $property; - $duplicateQuery = $db->select()->from('virtual_machine', $property) + $duplicateQuery = $db->select() + ->from('virtual_machine', $property) ->where("$property IS NOT NULL") ->group($property) ->having('(COUNT(*) > 1)'); - return $db->select()->from( - ['vm' => 'virtual_machine'], - [ + return $db->select() + ->from(['vm' => 'virtual_machine'], [ 'o.uuid', 'vm.guest_host_name', "vm.$property", 'vm.runtime_power_state', - 'o.overall_status', - ] - )->join( - ['o' => 'object'], - 'o.uuid = vm.uuid', - ['o.object_name'] - )->join( - ['dup' => $duplicateQuery], - "vm.$property = dup.$property", - [] - )->order($property)->order('object_name'); + 'o.overall_status' + ]) + ->join(['o' => 'object'], 'o.uuid = vm.uuid', ['o.object_name']) + ->join(['dup' => $duplicateQuery], "vm.$property = dup.$property", []) + ->order($property)->order('object_name'); } } diff --git a/library/Vspheredb/Web/Table/VsphereApiConnectionTable.php b/library/Vspheredb/Web/Table/VsphereApiConnectionTable.php index 8c14799a..ce755db8 100644 --- a/library/Vspheredb/Web/Table/VsphereApiConnectionTable.php +++ b/library/Vspheredb/Web/Table/VsphereApiConnectionTable.php @@ -4,12 +4,12 @@ class VsphereApiConnectionTable extends ArrayTable { - public function getColumnsToBeRendered() + public function getColumnsToBeRendered(): array { return [ $this->translate('VCenter'), $this->translate('Server'), - $this->translate('State'), + $this->translate('State') ]; } } diff --git a/library/Vspheredb/Web/Tabs/ConfigTabs.php b/library/Vspheredb/Web/Tabs/ConfigTabs.php index 6ba1d6de..8d773bbe 100644 --- a/library/Vspheredb/Web/Tabs/ConfigTabs.php +++ b/library/Vspheredb/Web/Tabs/ConfigTabs.php @@ -2,17 +2,16 @@ namespace Icinga\Module\Vspheredb\Web\Tabs; -use ipl\I18n\Translation; -use gipfl\IcingaWeb2\Widget\Tabs; use Exception; +use gipfl\IcingaWeb2\Widget\Tabs; use Icinga\Module\Vspheredb\Db; +use ipl\I18n\Translation; class ConfigTabs extends Tabs { use Translation; - /** @var Db|null */ - protected $connection; + protected ?Db $connection; public function __construct(?Db $connection = null) { @@ -21,14 +20,14 @@ public function __construct(?Db $connection = null) $this->assemble(); } - protected function assemble() + protected function assemble(): void { if ($this->connection) { $migrations = Db::migrationsForDb($this->connection); } else { try { $migrations = Db::migrationsForDb(Db::newConfiguredInstance()); - } catch (Exception $e) { + } catch (Exception) { $migrations = null; } } @@ -36,23 +35,23 @@ protected function assemble() if ($migrations && $migrations->hasSchema()) { $this->add('servers', [ 'label' => $this->translate('Servers'), - 'url' => 'vspheredb/configuration/servers', + 'url' => 'vspheredb/configuration/servers' ]); $this->add('perfdata', [ 'label' => $this->translate('Performance Data'), - 'url' => 'vspheredb/perfdata/consumers', + 'url' => 'vspheredb/perfdata/consumers' ]); // Disable Tab unless #160 is ready $this->add('monitoring', [ 'label' => $this->translate('Monitoring'), - 'url' => 'vspheredb/configuration/monitoring', + 'url' => 'vspheredb/configuration/monitoring' ]); } $this->add('database', [ 'label' => $this->translate('Database'), - 'url' => 'vspheredb/configuration/database', + 'url' => 'vspheredb/configuration/database' ]); } } diff --git a/library/Vspheredb/Web/Tabs/MainTabs.php b/library/Vspheredb/Web/Tabs/MainTabs.php index 7b80bf76..23d3ca64 100644 --- a/library/Vspheredb/Web/Tabs/MainTabs.php +++ b/library/Vspheredb/Web/Tabs/MainTabs.php @@ -2,21 +2,19 @@ namespace Icinga\Module\Vspheredb\Web\Tabs; -use ipl\I18n\Translation; -use gipfl\IcingaWeb2\Widget\Tabs; use Exception; +use gipfl\IcingaWeb2\Widget\Tabs; use Icinga\Authentication\Auth; use Icinga\Module\Vspheredb\Db; +use ipl\I18n\Translation; class MainTabs extends Tabs { use Translation; - /** @var Db|null */ - protected $connection; + protected ?Db $connection; - /** @var Auth */ - protected $auth; + protected Auth $auth; public function __construct(Auth $auth, ?Db $connection = null) { @@ -26,14 +24,14 @@ public function __construct(Auth $auth, ?Db $connection = null) $this->assemble(); } - protected function assemble() + protected function assemble(): void { if ($this->connection) { $connection = $this->connection; } else { try { $connection = Db::newConfiguredInstance(); - } catch (Exception $e) { + } catch (Exception) { $connection = null; } } @@ -44,8 +42,8 @@ protected function assemble() if ($migrations->hasSchema()) { $this->add('vcenters', [ - 'label' => $this->translate('vCenters'), - 'url' => 'vspheredb/vcenters', + 'label' => $this->translate('vCenters'), + 'url' => 'vspheredb/vcenters' ]); } } else { @@ -55,7 +53,7 @@ protected function assemble() if ($isAdmin && $migrations && $migrations->hasSchema()) { $this->add('daemon', [ 'label' => $this->translate('Daemon'), - 'url' => 'vspheredb/daemon', + 'url' => 'vspheredb/daemon' ]); } } diff --git a/library/Vspheredb/Web/Tabs/VCenterTabs.php b/library/Vspheredb/Web/Tabs/VCenterTabs.php index 1382c1e8..23e37713 100644 --- a/library/Vspheredb/Web/Tabs/VCenterTabs.php +++ b/library/Vspheredb/Web/Tabs/VCenterTabs.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Vspheredb\Web\Tabs; use gipfl\IcingaWeb2\Widget\Tabs; +use gipfl\Translation\TranslationHelper; use Icinga\Module\Vspheredb\DbObject\VCenter; use ipl\I18n\Translation; use Ramsey\Uuid\Uuid; @@ -11,8 +12,7 @@ class VCenterTabs extends Tabs { use Translation; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VCenter $vCenter) { @@ -21,21 +21,21 @@ public function __construct(VCenter $vCenter) $this->assemble(); } - protected function assemble() + protected function assemble(): void { $hexUuid = Uuid::fromBytes($this->vCenter->getUuid())->toString(); $this->add('vcenter', [ - 'label' => $this->translate('vCenter'), - 'url' => 'vspheredb/vcenter', - 'urlParams' => ['vcenter' => $hexUuid], + 'label' => $this->translate('vCenter'), + 'url' => 'vspheredb/vcenter', + 'urlParams' => ['vcenter' => $hexUuid] ])->add('clusters', [ - 'label' => $this->translate('Clusters'), - 'url' => 'vspheredb/resources/clusters', - 'urlParams' => ['vcenter' => $hexUuid], + 'label' => $this->translate('Clusters'), + 'url' => 'vspheredb/resources/clusters', + 'urlParams' => ['vcenter' => $hexUuid] ])->add('perfcounters', [ - 'label' => $this->translate('Counters'), - 'url' => 'vspheredb/perfdata/counters', - 'urlParams' => ['vcenter' => $hexUuid], + 'label' => $this->translate('Counters'), + 'url' => 'vspheredb/perfdata/counters', + 'urlParams' => ['vcenter' => $hexUuid] ]); } } diff --git a/library/Vspheredb/Web/Widget/AdditionalTableActions.php b/library/Vspheredb/Web/Widget/AdditionalTableActions.php index 5785d06f..790a84b1 100644 --- a/library/Vspheredb/Web/Widget/AdditionalTableActions.php +++ b/library/Vspheredb/Web/Widget/AdditionalTableActions.php @@ -2,27 +2,25 @@ namespace Icinga\Module\Vspheredb\Web\Widget; -use ipl\Html\Html; -use ipl\Html\HtmlDocument; use gipfl\IcingaWeb2\Icon; use gipfl\IcingaWeb2\Link; -use ipl\I18n\Translation; use gipfl\IcingaWeb2\Url; use Icinga\Authentication\Auth; use Icinga\Module\Vspheredb\Web\Table\BaseTable; +use ipl\Html\Html; +use ipl\Html\HtmlDocument; +use ipl\Html\HtmlElement; +use ipl\I18n\Translation; class AdditionalTableActions { use Translation; - /** @var Auth */ - protected $auth; + protected Auth $auth; - /** @var Url */ - protected $url; + protected Url $url; - /** @var BaseTable */ - protected $table; + protected BaseTable $table; public function __construct(BaseTable $table, Auth $auth, Url $url) { @@ -31,7 +29,7 @@ public function __construct(BaseTable $table, Auth $auth, Url $url) $this->table = $table; } - public function appendTo(HtmlDocument $parent) + public function appendTo(HtmlDocument $parent): static { $links = []; if ($this->hasPermission('vspheredb/export') && $this->urlAllowsExport($this->url)) { @@ -75,28 +73,20 @@ protected function urlAllowsExport(Url $url): bool return in_array($url->getPath(), [ 'vspheredb/vms', 'vspheredb/hosts', - 'vspheredb/datastores', + 'vspheredb/datastores' ]); } - protected function createShowSqlToggle() + protected function createShowSqlToggle(): Link { if ($this->url->getParam('format') === 'sql') { - $link = Link::create( - $this->translate('Hide SQL'), - $this->url->without('format') - ); - } else { - $link = Link::create( - $this->translate('Show SQL'), - $this->url->with('format', 'sql') - ); + return Link::create($this->translate('Hide SQL'), $this->url->without('format')); } - return $link; + return Link::create($this->translate('Show SQL'), $this->url->with('format', 'sql')); } - protected function toggleColumnsOptions() + protected function toggleColumnsOptions(): array { $links = []; $table = $this->table; @@ -125,9 +115,7 @@ protected function toggleColumnsOptions() if (in_array($alias, $enabled)) { $links[] = Link::create( $title, - $url->with('columns', implode(',', array_diff($enabled, [ - $alias - ]))), + $url->with('columns', implode(',', array_diff($enabled, [$alias]))), null, ['class' => 'icon-ok'] ); @@ -135,9 +123,7 @@ protected function toggleColumnsOptions() $disabled[] = $alias; $links[] = Link::create( $title, - $url->with('columns', implode(',', array_merge($enabled, [ - $alias - ]))), + $url->with('columns', implode(',', array_merge($enabled, [$alias]))), null, ['class' => 'icon-plus'] ); @@ -158,9 +144,9 @@ protected function toggleColumnsOptions() return $links; } - protected function moreOptions($links) + protected function moreOptions(array $links): HtmlElement { - $options = $this->ul([ + return $this->ul([ /*$this->li([ Link::create('Columns', '#', null, ['class' => 'icon-th-list']), $this->linkList($this->toggleColumnsOptions()) @@ -168,13 +154,11 @@ protected function moreOptions($links) $this->li([ Link::create(Icon::create('down-open'), '#'), $this->linkList($links) - ]), + ]) ], ['class' => 'nav']); - - return $options; } - protected function linkList($links) + protected function linkList(array $links): HtmlElement { $ul = Html::tag('ul'); @@ -185,22 +169,22 @@ protected function linkList($links) return $ul; } - protected function ulLi($content) + protected function ulLi($content): HtmlElement { return $this->ul($this->li($content)); } - protected function ul($content, $attributes = null) + protected function ul(mixed $content, ?array $attributes = null): HtmlElement { return Html::tag('ul', $attributes, $content); } - protected function li($content) + protected function li(mixed $content): HtmlElement { return Html::tag('li', null, $content); } - protected function hasPermission($permission) + protected function hasPermission($permission): bool { return $this->auth->hasPermission($permission); } diff --git a/library/Vspheredb/Web/Widget/Addon/IbmSpectrumProtectBackupRunDetails.php b/library/Vspheredb/Web/Widget/Addon/IbmSpectrumProtectBackupRunDetails.php index 67b7dfee..3b82e60c 100644 --- a/library/Vspheredb/Web/Widget/Addon/IbmSpectrumProtectBackupRunDetails.php +++ b/library/Vspheredb/Web/Widget/Addon/IbmSpectrumProtectBackupRunDetails.php @@ -14,6 +14,7 @@ class IbmSpectrumProtectBackupRunDetails extends NameValueTable /** * IbmSpectrumProtectBackupRunDetails constructor. + * * @param IbmSpectrumProtect $details */ public function __construct(IbmSpectrumProtect $details) @@ -21,18 +22,18 @@ public function __construct(IbmSpectrumProtect $details) $attributes = $details->requireParsedAttributes(); $optional = [ - $this->translate('Schedule') => $attributes['Schedule'], - $this->translate('Application Protection') => $attributes['Application Protection'], + $this->translate('Schedule') => $attributes['Schedule'], + $this->translate('Application Protection') => $attributes['Application Protection'] ]; $this->addNameValuePairs([ - $this->translate('Status') => $attributes['Status'], + $this->translate('Status') => $attributes['Status'], $this->translate('Last Run Time') => DateFormatter::formatDateTime($attributes['Last Run Time']), $this->translate('Data Transmitted') => Format::bytes($attributes['Data Transmitted']), - $this->translate('Duration') => DateFormatter::formatDuration($attributes['Duration']), - $this->translate('Type') => $attributes['Type'], - $this->translate('Data Mover') => $attributes['Data Mover'], - $this->translate('Snapshot Type') => $attributes['Snapshot Type'], + $this->translate('Duration') => DateFormatter::formatDuration($attributes['Duration']), + $this->translate('Type') => $attributes['Type'], + $this->translate('Data Mover') => $attributes['Data Mover'], + $this->translate('Snapshot Type') => $attributes['Snapshot Type'] ]); foreach ($optional as $name => $value) { diff --git a/library/Vspheredb/Web/Widget/Addon/NetBackupRunDetails.php b/library/Vspheredb/Web/Widget/Addon/NetBackupRunDetails.php index ce8779f9..de67587b 100644 --- a/library/Vspheredb/Web/Widget/Addon/NetBackupRunDetails.php +++ b/library/Vspheredb/Web/Widget/Addon/NetBackupRunDetails.php @@ -28,6 +28,7 @@ public function __construct(NetBackup $details) $this->translate('Excluded'), $this->translate('This VM has been excluded from Backup') ); + return; } if (isset($attributes['Job name'])) { @@ -56,17 +57,15 @@ public function __construct(NetBackup $details) } } - protected function renderBackupHost($name) + protected function renderBackupHost(string $name): Link|string { try { // TODO: this is ugly. $lookup = new CheckRelatedLookup(Db::newConfiguredInstance()); - $vm = $lookup->findOneBy('VirtualMachine', [ - 'guest_host_name' => $name - ]); + $vm = $lookup->findOneBy('VirtualMachine', ['guest_host_name' => $name]); return Link::create($name, 'vspheredb/vm', Util::uuidParams($vm->get('uuid'))); - } catch (NotFoundError $e) { + } catch (NotFoundError) { return $name; } } diff --git a/library/Vspheredb/Web/Widget/Addon/VRangerBackupRunDetails.php b/library/Vspheredb/Web/Widget/Addon/VRangerBackupRunDetails.php index 3c525663..a570c495 100644 --- a/library/Vspheredb/Web/Widget/Addon/VRangerBackupRunDetails.php +++ b/library/Vspheredb/Web/Widget/Addon/VRangerBackupRunDetails.php @@ -22,7 +22,7 @@ public function __construct(VRangerBackup $details) $this->translate('Result') => $attributes['Result'], $this->translate('Last Run Time') => DateFormatter::formatDateTime($attributes['Time']), $this->translate('Type') => $attributes['Type'], - $this->translate('Repository') => $attributes['Repository'], + $this->translate('Repository') => $attributes['Repository'] ]); } } diff --git a/library/Vspheredb/Web/Widget/Addon/VeeamBackupRunDetails.php b/library/Vspheredb/Web/Widget/Addon/VeeamBackupRunDetails.php index a0bdf099..1541dd00 100644 --- a/library/Vspheredb/Web/Widget/Addon/VeeamBackupRunDetails.php +++ b/library/Vspheredb/Web/Widget/Addon/VeeamBackupRunDetails.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Vspheredb\Web\Widget\Addon; use gipfl\IcingaWeb2\Widget\NameValueTable; +use gipfl\Translation\TranslationHelper; use Icinga\Date\DateFormatter; use Icinga\Module\Vspheredb\Addon\VeeamBackup; use ipl\I18n\Translation; @@ -13,6 +14,7 @@ class VeeamBackupRunDetails extends NameValueTable /** * VeeamBackupRunDetails constructor. + * * @param VeeamBackup $details */ public function __construct(VeeamBackup $details) @@ -23,7 +25,7 @@ public function __construct(VeeamBackup $details) $this->translate('Job name') => $attributes['Job name'], $this->translate('Last Run Time') => DateFormatter::formatDateTime($attributes['Time']), $this->translate('Backup host') => $attributes['Backup host'], - $this->translate('Backup folder') => $attributes['Backup folder'], + $this->translate('Backup folder') => $attributes['Backup folder'] ]); } } diff --git a/library/Vspheredb/Web/Widget/AlarmHeatmap.php b/library/Vspheredb/Web/Widget/AlarmHeatmap.php index 207d6f16..a46d8dc3 100644 --- a/library/Vspheredb/Web/Widget/AlarmHeatmap.php +++ b/library/Vspheredb/Web/Widget/AlarmHeatmap.php @@ -3,14 +3,14 @@ namespace Icinga\Module\Vspheredb\Web\Widget; use Icinga\Module\Vspheredb\Db; +use Zend_Db_Adapter_Abstract; use Zend_Db_Select as ZfSelect; class AlarmHeatmap { - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; - protected $query; + protected ?ZfSelect $query = null; public function __construct(Db $connection) { @@ -25,19 +25,18 @@ public function getEvents(): array protected function prepareQuery(): ZfSelect { $maxDays = 400; - return $this->db->select()->from('alarm_history', [ - // TODO: / 86400 + offset - 'day' => 'DATE(FROM_UNIXTIME(ts_event_ms / 1000))', - 'cnt' => 'COUNT(*)' - ])->where('ts_event_ms > ?', time() * 1000 - 86400 * $maxDays * 1000)->group('day'); + return $this->db->select() + ->from('alarm_history', [ + // TODO: / 86400 + offset + 'day' => 'DATE(FROM_UNIXTIME(ts_event_ms / 1000))', + 'cnt' => 'COUNT(*)' + ]) + ->where('ts_event_ms > ?', time() * 1000 - 86400 * $maxDays * 1000) + ->group('day'); } protected function getQuery(): ZfSelect { - if ($this->query === null) { - $this->query = $this->prepareQuery(); - } - - return $this->query; + return $this->query ??= $this->prepareQuery(); } } diff --git a/library/Vspheredb/Web/Widget/BiosInfo.php b/library/Vspheredb/Web/Widget/BiosInfo.php index 6a621219..a8f2b4bd 100644 --- a/library/Vspheredb/Web/Widget/BiosInfo.php +++ b/library/Vspheredb/Web/Widget/BiosInfo.php @@ -7,19 +7,18 @@ class BiosInfo extends HtmlDocument { - /** @var HostSystem */ - protected $host; + protected HostSystem $host; public function __construct(HostSystem $host) { $this->host = $host; } - protected function assemble() + protected function assemble(): void { $host = $this->host; $version = $host->get('bios_version'); - if ($releaseDate = $host->get('bios_release_date')) { + if ($host->get('bios_release_date')) { $releaseDate = date('Y-m-d', strtotime($host->get('bios_release_date'))); $this->add(sprintf('%s (%s)', $version, $releaseDate)); } diff --git a/library/Vspheredb/Web/Widget/CalendarForEvents.php b/library/Vspheredb/Web/Widget/CalendarForEvents.php index 1e0996ed..114f2bd2 100644 --- a/library/Vspheredb/Web/Widget/CalendarForEvents.php +++ b/library/Vspheredb/Web/Widget/CalendarForEvents.php @@ -12,36 +12,30 @@ class CalendarForEvents extends HtmlDocument { use Translation; - /** @var VMotionHeatmap|AlarmHeatmap */ - protected $calendars; + protected VMotionHeatmap|AlarmHeatmap $calendars; - /** @var Url */ - protected $baseUrl; + protected Url $baseUrl; /** @var int[] [r, g, b] */ - protected $colors; + protected array $colors; - public function __construct($calendars, Url $baseUrl, array $colors) + public function __construct(VMotionHeatmap|AlarmHeatmap $calendars, Url $baseUrl, array $colors) { $this->calendars = $calendars; $this->baseUrl = $baseUrl; $this->colors = $colors; } - protected function assemble() + protected function assemble(): void { $events = $this->calendars->getEvents(); if (empty($events)) { + $maxPerDay = 0; $this->add(Hint::warning($this->translate('No events found'))); - $maxPerDay = $total = 0; } else { $maxPerDay = max($events); $total = array_sum($events); - $this->add(Hint::ok( - $this->translate('%s events, max %s per day'), - $total, - $maxPerDay - )); + $this->add(Hint::ok($this->translate('%s events, max %s per day'), $total, $maxPerDay)); } $eventsPerMonth = []; @@ -49,9 +43,7 @@ protected function assemble() $month = substr($day, 0, 7); $eventsPerMonth[$month][$day] = $count; } - $div = Html::tag('div', [ - 'class' => 'event-heatmap-calendars', - ]); + $div = Html::tag('div', ['class' => 'event-heatmap-calendars']); $months = $this->prepareMonthList(); $colors = $this->colors; diff --git a/library/Vspheredb/Web/Widget/CalendarMonthSummary.php b/library/Vspheredb/Web/Widget/CalendarMonthSummary.php index d7560de2..d094d9f4 100644 --- a/library/Vspheredb/Web/Widget/CalendarMonthSummary.php +++ b/library/Vspheredb/Web/Widget/CalendarMonthSummary.php @@ -6,6 +6,7 @@ use gipfl\Format\LocalTimeFormat; use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Url; +use ipl\Html\Attributes; use ipl\Html\HtmlElement; use ipl\Html\Table; use ipl\I18n\Translation; @@ -17,38 +18,38 @@ class CalendarMonthSummary extends Table protected $defaultAttributes = [ 'data-base-target' => '_next', - 'class' => 'calendar', + 'class' => 'calendar' ]; - protected $today; + protected ?string $today = null; - protected $year; + protected int $year; - protected $month; + protected int $month; - protected $strMonth; + protected string $strMonth; - protected $strToday; + protected string $strToday; - protected $days = []; + protected array $days = []; - protected $calendar; + protected Calendar $calendar; - protected $showWeekNumbers = true; + protected bool $showWeekNumbers = true; - protected $showOtherMonth = false; + protected bool $showOtherMonth = false; - protected $showGrayFuture = true; + protected bool $showGrayFuture = true; - protected $title; + protected ?string $title = null; - protected $color = '255, 128, 0'; + protected string $color = '255, 128, 0'; - protected $forcedMax; + protected ?int $forcedMax = null; - protected $timeFormat; + protected LocalTimeFormat $timeFormat; - public function __construct($year, $month) + public function __construct(int $year, int $month) { $this->calendar = new Calendar(); $this->year = $year; @@ -58,24 +59,20 @@ public function __construct($year, $month) $this->timeFormat = new LocalTimeFormat(); } - public function setRgb($red, $green, $blue) + public function setRgb(int $red, int $green, int $blue): static { $this->color = sprintf('%d, %d, %d', $red, $green, $blue); return $this; } - public function addEvents($events, Url $baseUrl) + public function addEvents(array $events, Url $baseUrl): static { if (empty($events)) { return $this; } - if ($this->forcedMax === null) { - $max = max($events); - } else { - $max = $this->forcedMax; - } + $max = $this->forcedMax ?? max($events); foreach ($events as $day => $count) { if (! $this->hasDay($day)) { @@ -87,14 +84,14 @@ public function addEvents($events, Url $baseUrl) $alpha = $count / $max; if ($alpha > 0.4) { - $link->addAttributes(['class' => 'color-white']); + $link->addAttributes(Attributes::create(['class' => 'color-white'])); } $style = (new StyleWithNonce()) ->setModule('vspheredb') ->addFor($link, ['background-color' => sprintf('rgba(%s, %.2F)', $this->color, $alpha)]); - $link->addAttributes(['title' => sprintf('%d events', $count)]); + $link->addAttributes(Attributes::create(['title' => sprintf('%d events', $count)])); $this->getDay($day)->setContent([$link, $style]); } @@ -102,45 +99,38 @@ public function addEvents($events, Url $baseUrl) return $this; } - public function markNow($now = null) + public function markNow(?int $now = null): static { - if ($now === null) { - $now = time(); - } - $this->today = date('Y-m-d', $now); + $this->today = date('Y-m-d', $now ?? time()); return $this; } - public function setTitle($title) + public function setTitle(string $title): static { $this->title = $title; return $this; } - protected function getTitle() + protected function getTitle(): string { - if ($this->title === null) { - $this->title = $this->getMonthName() . ' ' . $this->year; - } - - return $this->title; + return $this->title ??= $this->getMonthName() . ' ' . $this->year; } - public function forceMax($max) + public function forceMax(int $max): static { $this->forcedMax = $max; return $this; } - protected function getMonthAsTimestamp() + protected function getMonthAsTimestamp(): int { return strtotime($this->strMonth . '-01'); } - protected function assemble() + protected function assemble(): void { $this->setCaption($this->getTitle()); $this->getHeader()->add($this->createWeekdayHeader()); @@ -194,40 +184,37 @@ protected function createDay(string $day): HtmlElement $this->days[$day] = $td; if ($otherMonth) { - $td->addAttributes(['class' => 'other-month']); + $td->addAttributes(Attributes::create(['class' => 'other-month'])); } elseif ($this->showGrayFuture && $day > $this->strToday) { - $td->addAttributes(['class' => 'future-day']); + $td->addAttributes(Attributes::create(['class' => 'future-day'])); } // TODO: today VS strToday?! if ($day === $this->today) { - $td->addAttributes(['class' => 'today']); + $td->addAttributes(Attributes::create(['class' => 'today'])); } return $td; } - protected function weekRow($cw) + protected function weekRow($cw): HtmlElement { $row = Table::tr(); if ($this->showWeekNumbers) { - $row->add(Table::th(sprintf('%02d', $cw), [ - 'title' => sprintf($this->translate('Calendar Week %d'), $cw) - ])); + $row->add(Table::th(sprintf('%02d', $cw), ['title' => sprintf($this->translate('Calendar Week %d'), $cw)])); } return $row; } - protected function getMonthName() + protected function getMonthName(): string { return $this->timeFormat->getMonthName($this->getMonthAsTimestamp()); - return date('F', $this->getMonthAsTimestamp()); } - protected function createWeekdayHeader() + protected function createWeekdayHeader(): HtmlElement { $cols = $this->calendar->listShortWeekDayNames(); if ($this->showWeekNumbers) { diff --git a/library/Vspheredb/Web/Widget/CheckPluginHelper.php b/library/Vspheredb/Web/Widget/CheckPluginHelper.php index 117bdbff..30627151 100644 --- a/library/Vspheredb/Web/Widget/CheckPluginHelper.php +++ b/library/Vspheredb/Web/Widget/CheckPluginHelper.php @@ -11,11 +11,11 @@ class CheckPluginHelper public static function colorizeOutput(string $output): HtmlString { $pattern = '/\[(OK|WARNING|CRITICAL|UNKNOWN)]\s/'; - $safeString = (new Text($output))->render(); - $safeString = preg_replace_callback($pattern, function ($match) { - $state = strtolower($match[1]); - return Html::tag('span', ['class' => ['check-result', "state-$state"]], $match[1]) . ' '; - }, $safeString); + $safeString = preg_replace_callback($pattern, fn($match) => Html::tag( + 'span', + ['class' => ['check-result', 'state-' . strtolower($match[1])]], + $match[1] + ) . ' ', (new Text($output))->render()); return new HtmlString($safeString); } } diff --git a/library/Vspheredb/Web/Widget/CompactInOutSparkline.php b/library/Vspheredb/Web/Widget/CompactInOutSparkline.php index c52cf9ed..4b8a6b5e 100644 --- a/library/Vspheredb/Web/Widget/CompactInOutSparkline.php +++ b/library/Vspheredb/Web/Widget/CompactInOutSparkline.php @@ -2,8 +2,10 @@ namespace Icinga\Module\Vspheredb\Web\Widget; +use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use ipl\Html\HtmlElement; class CompactInOutSparkline extends BaseHtmlElement { @@ -11,33 +13,34 @@ class CompactInOutSparkline extends BaseHtmlElement protected $defaultAttributes = ['class' => 'sparks']; - public function __construct($in, $out) + public function __construct(array|string|null $in, array|string|null $out) { if ($in !== null) { $this->add( $this->makeSparkLine($in) - ->addAttributes(['class' => 'in']) + ->addAttributes(Attributes::create(['class' => 'in'])) ); } if ($out !== null && $out !== '0,0,0,0,0') { $this->add( $this->makeSparkLine($this->negateString($out)) - ->addAttributes(['class' => 'out']) + ->addAttributes(Attributes::create(['class' => 'out'])) ); } } - protected function negateString($valueString) + protected function negateString(string $valueString): string { return '-' . implode(',-', explode(',', $valueString)); } - protected function makeSparkLine($values) + protected function makeSparkLine($values): ?HtmlElement { if ($values === null) { return null; } + return Html::tag('span', [ 'class' => 'sparkline', 'sparkType' => 'bar', diff --git a/library/Vspheredb/Web/Widget/ComputeClusterHeader.php b/library/Vspheredb/Web/Widget/ComputeClusterHeader.php index d30f2477..40649a59 100644 --- a/library/Vspheredb/Web/Widget/ComputeClusterHeader.php +++ b/library/Vspheredb/Web/Widget/ComputeClusterHeader.php @@ -2,14 +2,14 @@ namespace Icinga\Module\Vspheredb\Web\Widget; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\DbObject\ComputeCluster; use ipl\Html\Html; use ipl\Html\HtmlDocument; class ComputeClusterHeader extends HtmlDocument { - /** @var ComputeCluster */ - protected $computeCluster; + protected ComputeCluster $computeCluster; public function __construct(ComputeCluster $computeCluster) { @@ -17,35 +17,20 @@ public function __construct(ComputeCluster $computeCluster) } /** - * @throws \Icinga\Exception\NotFoundError + * @throws NotFoundError */ - protected function assemble() + protected function assemble(): void { $computeCluster = $this->computeCluster; $object = $computeCluster->object(); $overallStatusRenderer = new OverallStatusRenderer(); - $icons = [ - $overallStatusRenderer($object->get('overall_status')), - ]; + $icons = [$overallStatusRenderer($object->get('overall_status'))]; $stats = $computeCluster->calculateStats(); - $cpu = new CpuAbsoluteUsage( - $stats->overall_cpu_usage, - $stats->hardware_cpu_cores - ); - $mem = new MemoryUsage( - $stats->overall_memory_usage_mb, - $stats->hardware_memory_size_mb - ); - $title = Html::tag('h1', [ - $computeCluster->get('object_name'), - $icons - ]); - $this->add([ - $cpu, - $title, - $mem - ]); + $cpu = new CpuAbsoluteUsage((int) $stats->overall_cpu_usage, $stats->hardware_cpu_cores); + $mem = new MemoryUsage($stats->overall_memory_usage_mb, $stats->hardware_memory_size_mb); + $title = Html::tag('h1', [$computeCluster->get('object_name'), $icons]); + $this->add([$cpu, $title, $mem]); } } diff --git a/library/Vspheredb/Web/Widget/Config/ProposeMigrations.php b/library/Vspheredb/Web/Widget/Config/ProposeMigrations.php index afd60af2..fc61b502 100644 --- a/library/Vspheredb/Web/Widget/Config/ProposeMigrations.php +++ b/library/Vspheredb/Web/Widget/Config/ProposeMigrations.php @@ -8,6 +8,7 @@ use Icinga\Authentication\Auth; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Web\Form\ApplyMigrationsForm; +use ipl\Html\Contract\Form; use ipl\Html\HtmlDocument; use ipl\I18n\Translation; use Psr\Http\Message\ServerRequestInterface; @@ -27,20 +28,17 @@ class ProposeMigrations extends HtmlDocument { use Translation; - /** @var Db */ - protected $db; + protected Db $db; - /** @var ServerRequestInterface */ - protected $request; + protected ServerRequestInterface $request; - /** @var Auth */ - protected $auth; + protected Auth $auth; - protected $requiredPermission = 'vspheredb/admin'; + protected string $requiredPermission = 'vspheredb/admin'; - protected $appliedMigrations = false; + protected bool $appliedMigrations = false; - protected $failed = false; + protected bool $failed = false; public function __construct(Db $db, Auth $auth, ServerRequestInterface $request) { @@ -54,9 +52,10 @@ public function __construct(Db $db, Auth $auth, ServerRequestInterface $request) * * @return bool */ - public function hasAppliedMigrations() + public function hasAppliedMigrations(): bool { $this->ensureAssembled(); + return $this->appliedMigrations; } @@ -65,13 +64,14 @@ public function hasAppliedMigrations() * * @return bool */ - public function hasFailed() + public function hasFailed(): bool { $this->ensureAssembled(); + return $this->failed; } - protected function assemble() + protected function assemble(): void { try { if ($this->auth->hasPermission($this->requiredPermission)) { @@ -84,15 +84,14 @@ protected function assemble() } } - protected function showEventualProblems(Db $db) + protected function showEventualProblems(Db $db): void { $migrations = Db::migrationsForDb($db); if ($migrations->hasSchema()) { if ($migrations->hasPendingMigrations()) { $this->add(Hint::warning($this->translate( - 'There are pending Database Schema Migrations. Please ask' - . ' an Administrator to apply them now!' + 'There are pending Database Schema Migrations. Please ask an Administrator to apply them now!' ))); } } else { @@ -103,15 +102,14 @@ protected function showEventualProblems(Db $db) } } - protected function showMigrations(Db $db) + protected function showMigrations(Db $db): void { $migrations = Db::migrationsForDb($db); if ($migrations->hasSchema()) { if ($migrations->hasPendingMigrations()) { $this->add(Hint::warning($this->translate( - 'There are pending Database Schema Migrations. Please apply' - . ' them now!' + 'There are pending Database Schema Migrations. Please apply them now!' ))); $this->addForm($migrations); } @@ -137,11 +135,11 @@ protected function showMigrations(Db $db) } } - protected function addForm(Migrations $migrations) + protected function addForm(Migrations $migrations): void { $this->add( (new ApplyMigrationsForm($migrations)) - ->on(ApplyMigrationsForm::ON_SUCCESS, function () { + ->on(Form::ON_SUBMIT, function () { $this->appliedMigrations = true; }) ->handleRequest($this->request) diff --git a/library/Vspheredb/Web/Widget/CpuAbsoluteUsage.php b/library/Vspheredb/Web/Widget/CpuAbsoluteUsage.php index 046b1527..029e189d 100644 --- a/library/Vspheredb/Web/Widget/CpuAbsoluteUsage.php +++ b/library/Vspheredb/Web/Widget/CpuAbsoluteUsage.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Vspheredb\Web\Widget; use Icinga\Module\Vspheredb\Format; +use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; use ipl\I18n\Translation; @@ -13,19 +14,12 @@ class CpuAbsoluteUsage extends BaseHtmlElement protected $tag = 'div'; - protected $defaultAttributes = [ - 'class' => 'cpu' - ]; + protected $defaultAttributes = ['class' => 'cpu']; - public function __construct($mhz, $cores = null, $perCore = 2000) + public function __construct(int $mhz, ?int $cores = null, int $perCore = 2000) { $class = null; if ($cores !== null) { - if (false) { - $this->add(Html::tag('span', [ - 'class' => 'cpu-count' - ], sprintf($this->translate('%d CPUs'), $cores))); - } $usedPerCore = $mhz / $cores; if ($usedPerCore / $perCore > 0.7) { $class = 'critical'; @@ -35,16 +29,12 @@ public function __construct($mhz, $cores = null, $perCore = 2000) } if ($class !== null) { - $this->addAttributes(['class' => $class]); + $this->addAttributes(Attributes::create(['class' => $class])); } [$value, $unit] = Format::mhzWithSeparateUnit($mhz); $this->add([ - Html::tag('span', [ - 'class' => 'cpu-consumption' - ], $value), - Html::tag('span', [ - 'class' => 'cpu-unit' - ], $unit), + Html::tag('span', ['class' => 'cpu-consumption'], $value), + Html::tag('span', ['class' => 'cpu-unit'], $unit) ])->setSeparator("\n"); } } diff --git a/library/Vspheredb/Web/Widget/CpuUsage.php b/library/Vspheredb/Web/Widget/CpuUsage.php index 8e223a40..d446ba56 100644 --- a/library/Vspheredb/Web/Widget/CpuUsage.php +++ b/library/Vspheredb/Web/Widget/CpuUsage.php @@ -6,5 +6,9 @@ class CpuUsage extends UsageBar { - protected $formatter = [Format::class, 'mhz']; + public function __construct(int|float|null $used, int|float|null $capacity) + { + parent::__construct($used, $capacity); + $this->formatter = Format::mhz(...); + } } diff --git a/library/Vspheredb/Web/Widget/CustomValueDetails.php b/library/Vspheredb/Web/Widget/CustomValueDetails.php index c861963d..5261758d 100644 --- a/library/Vspheredb/Web/Widget/CustomValueDetails.php +++ b/library/Vspheredb/Web/Widget/CustomValueDetails.php @@ -5,34 +5,26 @@ use ipl\I18n\Translation; use gipfl\Web\Table\NameValueTable; use Icinga\Module\Vspheredb\Addon\IbmSpectrumProtect; -use Icinga\Module\Vspheredb\Addon\SimpleBackupTool; use Icinga\Module\Vspheredb\Addon\NetBackup; +use Icinga\Module\Vspheredb\Addon\SimpleBackupTool; use Icinga\Module\Vspheredb\Addon\VRangerBackup; -use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use Icinga\Module\Vspheredb\DbObject\CustomValues; use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; -use InvalidArgumentException; use ipl\Html\HtmlDocument; class CustomValueDetails extends HtmlDocument { use Translation; - /** @var HostSystem|VirtualMachine */ - protected $object; + protected HostSystem|VirtualMachine $object; - public function __construct(BaseDbObject $object) + public function __construct(HostSystem|VirtualMachine $object) { - if (! $object instanceof HostSystem && ! $object instanceof VirtualMachine) { - throw new InvalidArgumentException( - 'HostSystem or VirtualMachine expected, got ' . \get_class($object) - ); - } $this->object = $object; } - protected function assemble() + protected function assemble(): void { $object = $this->object; $this->prepend(new SubTitle($this->translate('Custom Values'), 'th-list')); @@ -45,7 +37,7 @@ protected function assemble() 'Application' => 'WebSphere Application Server', 'Installation Date' => '2020-01-02', 'Cost Center' => '48145', - 'Department' => 'Web Shop', + 'Department' => 'Web Shop' ]); } if ($values->isEmpty()) { @@ -56,15 +48,9 @@ protected function assemble() } } - protected function stripBackupToolCustomValues(CustomValues $values) + protected function stripBackupToolCustomValues(CustomValues $values): void { - $tools = [ - new IbmSpectrumProtect(), - new NetBackup(), - new VRangerBackup(), - ]; - - foreach ($tools as $tool) { + foreach ([new IbmSpectrumProtect(), new NetBackup(), new VRangerBackup()] as $tool) { if ($tool instanceof SimpleBackupTool) { $tool->stripCustomValues($values); } diff --git a/library/Vspheredb/Web/Widget/DatastoreUsage.php b/library/Vspheredb/Web/Widget/DatastoreUsage.php index a0bfcdd7..3315af8a 100644 --- a/library/Vspheredb/Web/Widget/DatastoreUsage.php +++ b/library/Vspheredb/Web/Widget/DatastoreUsage.php @@ -7,9 +7,11 @@ use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\Util; use Icinga\Util\Format; +use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; use ipl\I18n\Translation; use ipl\Web\Compat\StyleWithNonce; +use Zend_Db_Adapter_Abstract; class DatastoreUsage extends BaseHtmlElement { @@ -22,61 +24,52 @@ class DatastoreUsage extends BaseHtmlElement 'data-base-target' => '_next' ]; - /** @var Datastore */ - protected $datastore; + protected Datastore $datastore; - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected ?Zend_Db_Adapter_Abstract $db; - /** @var string */ - protected $uuid; + protected ?string $uuid = null; - /** @var int */ - protected $capacity; + protected int $capacity; - /** @var int */ - protected $uncommitted; + protected int $uncommitted; - protected $gotPercent = 0; + protected float $gotPercent = 0; - protected $baseUrl = 'vspheredb/vm'; + protected string $baseUrl = 'vspheredb/vm'; - /** @var Link[] Array key is the VirtualMachine id */ - protected $diskLinks; + /** @var ?Link[] Array key is the VirtualMachine id */ + protected ?array $diskLinks = null; public function __construct(Datastore $datastore) { - $this->datastore = $datastore; - $this->uuid = $datastore->get('uuid'); - $this->capacity = (int) $datastore->get('capacity'); + $this->datastore = $datastore; + $this->uuid = $datastore->get('uuid'); + $this->capacity = (int) $datastore->get('capacity'); $this->uncommitted = (int) $datastore->get('uncommitted'); $this->db = $datastore->getDb(); } - public function setCapacity($capacity) + public function setCapacity(int $capacity): static { $this->capacity = $capacity; + return $this; } - public function setBaseUrl($url) + public function setBaseUrl(string $url): static { $this->baseUrl = $url; return $this; } - public function loadAllVmDisks() + public function loadAllVmDisks(): static { $query = $this->db->select() - ->from( - ['vdu' => 'vm_datastore_usage'], - ['o.uuid', 'o.object_name', 'vdu.committed', 'vdu.uncommitted'] - )->join( - ['o' => 'object'], - 'o.uuid = vdu.vm_uuid', - [] - )->where('vdu.datastore_uuid = ?', $this->datastore->get('uuid')) + ->from(['vdu' => 'vm_datastore_usage'], ['o.uuid', 'o.object_name', 'vdu.committed', 'vdu.uncommitted']) + ->join(['o' => 'object'], 'o.uuid = vdu.vm_uuid', []) + ->where('vdu.datastore_uuid = ?', $this->datastore->get('uuid')) // ->order('o.object_name'); ->order('vdu.committed DESC'); @@ -117,7 +110,7 @@ public function loadAllVmDisks() return $this; } - public function addDiskFromDbRow($row) + public function addDiskFromDbRow(object $row): static { $info = $this->makeDisk($row); if ($info !== null) { @@ -127,20 +120,19 @@ public function addDiskFromDbRow($row) return $this; } - public function addFreeDatastoreSpace() + public function addFreeDatastoreSpace(): static { if ($this->capacity === 0) { return $this; } - $title = sprintf('Free space'); + $title = 'Free space'; $free = $this->datastore->get('free_space'); if ($this->uncommitted < $free) { $class = 'free'; } elseif ($this->uncommitted > 2 * $this->capacity) { - $title = sprintf('Committed space'); + $title = 'Committed space'; $class = 'free overcommitted-twice'; } else { - $title = sprintf('Free space'); $class = 'free overcommitted'; } @@ -154,25 +146,19 @@ public function addFreeDatastoreSpace() ['class' => 'unknown'] ); } - $this->addVmDisk( - $title, - $percent, - null, - ['class' => $class] - ); - return $this; + return $this->addVmDisk($title, $percent, null, ['class' => $class]); } /** - * @param $title - * @param $percent + * @param string $title + * @param float $percent * @param ?string $vmUuid * @param array $attributes * * @return $this */ - public function addVmDisk($title, $percent, ?string $vmUuid = null, array $attributes = []): static + public function addVmDisk(string $title, float $percent, ?string $vmUuid = null, array $attributes = []): static { if ($vmUuid) { $url = $this->baseUrl; @@ -195,7 +181,7 @@ public function addVmDisk($title, $percent, ?string $vmUuid = null, array $attri ->setModule('vspheredb') ->addFor($link, ['width' => sprintf('%.3F%%; ', $percent)]); - $link->addAttributes($attributes); + $link->addAttributes(Attributes::create($attributes)); if ($vmUuid) { $alpha = (20 + (crc32(sha1($vmUuid . $this->uuid)) % 60)) / 100; @@ -203,12 +189,11 @@ public function addVmDisk($title, $percent, ?string $vmUuid = null, array $attri $style->addFor($link, ['background-color' => $color]); $this->diskLinks[$vmUuid] = $link; } - $this->add([$link, $style]); - return $this; + return $this->add([$link, $style]); } - protected function makeDisk($dbRow) + protected function makeDisk(object $dbRow): ?object { $size = $dbRow->committed + $dbRow->uncommitted; if ($size === 0) { @@ -216,17 +201,15 @@ protected function makeDisk($dbRow) } $share = (object) [ - 'vm_uuid' => $dbRow->uuid, - 'name' => $dbRow->object_name, - 'size' => $size, - 'used' => $dbRow->committed, + 'vm_uuid' => $dbRow->uuid, + 'name' => $dbRow->object_name, + 'size' => $size, + 'used' => $dbRow->committed, 'used_percent' => ($dbRow->committed / $size) * 100, 'datastore_percent' => ($dbRow->committed / $this->capacity) * 100, 'uncommitted' => $dbRow->uncommitted, - 'uncommitted_percent' => $this->uncommitted > 0 - ? ($dbRow->uncommitted / $this->uncommitted) * 100 - : 0, - 'extra-class' => null, + 'uncommitted_percent' => $this->uncommitted > 0 ? ($dbRow->uncommitted / $this->uncommitted) * 100 : 0, + 'extra-class' => null ]; $share->title = sprintf( '%s (%.2f%% of %s) used by %s', @@ -239,7 +222,7 @@ protected function makeDisk($dbRow) return $share; } - protected function bytes($bytes) + protected function bytes(int $bytes): string { return Format::bytes($bytes, Format::STANDARD_IEC); } diff --git a/library/Vspheredb/Web/Widget/DelayedPerfdataRenderer.php b/library/Vspheredb/Web/Widget/DelayedPerfdataRenderer.php index 3541366a..f72b2300 100644 --- a/library/Vspheredb/Web/Widget/DelayedPerfdataRenderer.php +++ b/library/Vspheredb/Web/Widget/DelayedPerfdataRenderer.php @@ -2,40 +2,39 @@ namespace Icinga\Module\Vspheredb\Web\Widget; -use ipl\Html\DeferredText; use Icinga\Module\Vspheredb\Web\Table\SimpleColumn; -use Icinga\Module\Vspheredb\Web\Table\TableColumn; +use ipl\Html\DeferredText; +use Zend_Db_Adapter_Abstract; class DelayedPerfdataRenderer { - protected $requiredVms = []; + protected array $requiredVms = []; - protected $perf; + protected ?array $perf = null; - protected $counters = [ + protected array $counters = [ 526 => 'net.bytesRx', 527 => 'net.bytesRx', 171 => 'virtualDisk.numberReadAveraged', - 172 => 'virtualDisk.numberWriteAveraged', + 172 => 'virtualDisk.numberWriteAveraged' ]; - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; - public function __construct(\Zend_Db_Adapter_Abstract $db) + public function __construct(Zend_Db_Adapter_Abstract $db) { $this->db = $db; } - public function requireVm($uuid) + public function requireVm(string $uuid): void { $this->requiredVms[] = $uuid; } /** - * @return TableColumn + * @return SimpleColumn */ - public function getDiskColumn() + public function getDiskColumn(): SimpleColumn { return (new SimpleColumn('disk_io_perf', '5x5min Disk I/O', 'o.uuid')) ->setRenderer(function ($row) { @@ -46,9 +45,9 @@ public function getDiskColumn() } /** - * @return TableColumn + * @return SimpleColumn */ - public function getNetColumn() + public function getNetColumn(): SimpleColumn { return (new SimpleColumn('network_io_perf', 'Network I/O (perf)', 'o.uuid')) ->setRenderer(function ($row) { @@ -59,9 +58,9 @@ public function getNetColumn() } /** - * @return TableColumn + * @return SimpleColumn */ - public function getCurrentNetColumn() + public function getCurrentNetColumn(): SimpleColumn { return (new SimpleColumn('network_io', 'Network I/O', 'o.uuid')) ->setRenderer(function ($row) { @@ -72,9 +71,9 @@ public function getCurrentNetColumn() } /** - * @return TableColumn + * @return SimpleColumn */ - public function getCurrentDiskColumn() + public function getCurrentDiskColumn(): SimpleColumn { return (new SimpleColumn('disk_io', 'Disk I/O', 'o.uuid')) ->setRenderer(function ($row) { @@ -84,25 +83,23 @@ public function getCurrentDiskColumn() }); } - protected function formatMicroSeconds($num) + protected function formatMicroSeconds(int $num): string { if ($num > 500) { return sprintf('%0.2Fms', $num / 1000); - } else { - return sprintf('%dµs', $num); } + + return sprintf('%dµs', $num); } - protected function formatKiloBytesPerSecond($num) + protected function formatKiloBytesPerSecond(int $num): string { $num *= 8; - if ($num > 500000) { - return sprintf('%0.2F Gbit/s', $num / 1024 / 1024); - } elseif ($num > 500) { - return sprintf('%0.2F Mbit/s', $num / 1024); - } else { - return sprintf('%0.2F Kbit/s', $num); - } + return match (true) { + $num > 500000 => sprintf('%0.2F Gbit/s', $num / 1024 / 1024), + $num > 500 => sprintf('%0.2F Mbit/s', $num / 1024), + default => sprintf('%0.2F Kbit/s', $num) + }; } /** @@ -118,16 +115,9 @@ protected function createKbInOut(string $uuid, string $instance, int $c1, int $c return DeferredText::create(function () use ($uuid, $instance, $c1, $c2) { $in = explode(',', $this->getVmValues($uuid, $instance, $c1)); $out = explode(',', $this->getVmValues($uuid, $instance, $c2)); - if ($in[0] === '') { - $in = '-'; - } else { - $in = $this->formatKiloBytesPerSecond(array_pop($in)); - } - if ($out[0] === '') { - $out = '-'; - } else { - $out = $this->formatKiloBytesPerSecond(array_pop($out)); - } + + $in = $in[0] === '' ? '-' : $this->formatKiloBytesPerSecond(array_pop($in)); + $out = $out[0] === '' ? '-' : $this->formatKiloBytesPerSecond(array_pop($out)); return sprintf('%s / %s', $in, $out); })->setEscaped(); @@ -160,9 +150,7 @@ protected function createPerfInOut(string $uuid, string $instance, int $c1, int */ protected function getVmValues(string $name, string $instance, int $counter): ?array { - if ($this->perf === null) { - $this->perf = $this->fetchPerf(); - } + $this->perf ??= $this->fetchPerf(); if ( array_key_exists($name, $this->perf) @@ -170,12 +158,12 @@ protected function getVmValues(string $name, string $instance, int $counter): ?a && array_key_exists($counter, $this->perf[$name][$instance]) ) { return $this->perf[$name][$instance][$counter]; - } else { - return null; } + + return null; } - protected function fetchPerf() + protected function fetchPerf(): array { $db = $this->db; @@ -184,16 +172,18 @@ protected function fetchPerf() "COALESCE(value_minus3, '0')", "COALESCE(value_minus2, '0')", "COALESCE(value_minus1, '0')", - 'value_last', + 'value_last' ]) . ')'; - $query = $db->select()->from('counter_300x5', [ - 'name' => 'object_uuid', - 'instance', - 'counter_key', - 'value' => $values, - 'value_last' - ])->where('object_uuid IN (?)', $this->requiredVms) + $query = $db->select() + ->from('counter_300x5', [ + 'name' => 'object_uuid', + 'instance', + 'counter_key', + 'value' => $values, + 'value_last' + ]) + ->where('object_uuid IN (?)', $this->requiredVms) ->where('instance IN (?)', ['', 'scsi0:0']) ->where('counter_key IN (?)', array_keys($this->counters)); diff --git a/library/Vspheredb/Web/Widget/Documentation.php b/library/Vspheredb/Web/Widget/Documentation.php index 47bdee96..2c61cb5a 100644 --- a/library/Vspheredb/Web/Widget/Documentation.php +++ b/library/Vspheredb/Web/Widget/Documentation.php @@ -20,10 +20,11 @@ class Documentation protected const PUBLIC_URL_MAP = [ 'vspheredb' => 'icinga-vsphere-integration', - 'director' => 'icinga-director', + 'director' => 'icinga-director' ]; protected ApplicationBootstrap $app; + protected Auth $auth; // true links to GitHub, false to icinga.com @@ -36,40 +37,36 @@ public function __construct(ApplicationBootstrap $app, Auth $auth) } /** - * @param $label + * @param string $label * @param string $module - * @param $chapter - * @param $title + * @param string $chapter + * @param ?string $title * * @return Link|HtmlElement */ - public static function link($label, string $module, $chapter, $title = null): Link|HtmlElement + public static function link(string $label, string $module, string $chapter, ?string $title = null): Link|HtmlElement { - $doc = new static(Icinga::app(), Auth::getInstance()); - - return $doc->getModuleLink($label, $module, $chapter, $title); + return (new static(Icinga::app(), Auth::getInstance()))->getModuleLink($label, $module, $chapter, $title); } /** - * @param $label + * @param string $label * @param string $module - * @param $chapter - * @param $title + * @param string $chapter + * @param ?string $title * * @return Link|HtmlElement */ - public function getModuleLink($label, string $module, $chapter, $title = null): Link|HtmlElement - { + public function getModuleLink( + string $label, + string $module, + string $chapter, + ?string $title = null + ): Link|HtmlElement { if ($title !== null) { - $title = sprintf( - $this->translate('Click to read our documentation: %s'), - $title - ); + $title = sprintf($this->translate('Click to read our documentation: %s'), $title); } - $baseParams = [ - 'class' => 'icon-book', - 'title' => $title, - ]; + $baseParams = ['class' => 'icon-book', 'title' => $title]; if ($this->hasAccessToDocumentationModule()) { return Link::create( $label, @@ -79,22 +76,19 @@ public function getModuleLink($label, string $module, $chapter, $title = null): ); } - $baseParams = [ - 'target' => '_blank', - 'rel' => 'noreferrer', - ]; + $baseParams = ['target' => '_blank', 'rel' => 'noreferrer']; if ($this->linkToGitHub || ! isset(self::PUBLIC_URL_MAP[$module])) { - return Html::tag('a', [ - 'href' => $this->githubDocumentationUrl($module, $chapter), - ] + $baseParams, $label); + return Html::tag('a', ['href' => $this->githubDocumentationUrl($module, $chapter)] + $baseParams, $label); } - return Html::tag('a', [ - 'href' => $this->icingaDocumentationUrl(self::PUBLIC_URL_MAP[$module], $chapter), - ] + $baseParams, $label); + return Html::tag( + 'a', + ['href' => $this->icingaDocumentationUrl(self::PUBLIC_URL_MAP[$module], $chapter)] + $baseParams, + $label + ); } - protected function getModuleDocumentationUrl($moduleName, $chapter): string + protected function getModuleDocumentationUrl(string $moduleName, string $chapter): string { return sprintf( 'doc/module/%s/chapter/%s', @@ -103,7 +97,7 @@ protected function getModuleDocumentationUrl($moduleName, $chapter): string ); } - protected function githubDocumentationUrl($module, $chapter): string + protected function githubDocumentationUrl(string $module, string $chapter): string { return sprintf( "https://github.com/Icinga/icingaweb2-module-%s/blob/master/doc/%s.md", @@ -112,7 +106,7 @@ protected function githubDocumentationUrl($module, $chapter): string ); } - protected function icingaDocumentationUrl($module, $chapter): string + protected function icingaDocumentationUrl(string $module, string $chapter): string { return sprintf( 'https://icinga.com/docs/%s/latest/doc/%s/', @@ -123,7 +117,6 @@ protected function icingaDocumentationUrl($module, $chapter): string protected function hasAccessToDocumentationModule(): bool { - return $this->app->getModuleManager()->hasLoaded('doc') - && $this->auth->hasPermission('module/doc'); + return $this->app->getModuleManager()->hasLoaded('doc') && $this->auth->hasPermission('module/doc'); } } diff --git a/library/Vspheredb/Web/Widget/GrafanaVmPanel.php b/library/Vspheredb/Web/Widget/GrafanaVmPanel.php index df3342a3..1198ca2e 100644 --- a/library/Vspheredb/Web/Widget/GrafanaVmPanel.php +++ b/library/Vspheredb/Web/Widget/GrafanaVmPanel.php @@ -13,17 +13,14 @@ */ class GrafanaVmPanel extends HtmlDocument { - /** @var ManagedObject */ - protected $object; + protected ManagedObject $object; - /** @var int */ - protected $panels; + /** @var int[] */ + protected array $panels; - /** @var string|null */ - protected $interface; + protected ?string $interface; - /** @var string|null */ - protected $disk; + protected ?string $disk; /** * @param ManagedObject $object @@ -31,7 +28,7 @@ class GrafanaVmPanel extends HtmlDocument * @param ?string $interface * @param ?string $disk */ - public function __construct(ManagedObject $object, array $panels, $interface = 'All', $disk = 'All') + public function __construct(ManagedObject $object, array $panels, ?string $interface = 'All', ?string $disk = 'All') { $this->object = $object; $this->panels = $panels; @@ -39,7 +36,7 @@ public function __construct(ManagedObject $object, array $panels, $interface = ' $this->disk = $disk; } - protected function assemble() + protected function assemble(): void { $width = floor(100 / count($this->panels)); foreach ($this->panels as $id) { @@ -47,21 +44,18 @@ protected function assemble() 'src' => $this->panelUrl($id), 'width' => $width . '%', 'height' => 200, - 'frameborder' => 0, + 'frameborder' => 0 ])); } } - protected function panelUrl($panelId) + protected function panelUrl(int $panelId): string { // &from=1636834148559&to=1636838149732 $orgId = 1; $dsName = 'vSphereDB'; $dashboard = 'Icinga-vSphereDB-VirtualMachineDetails'; - $url = sprintf( - 'https://grafana.example.com:3000/d-solo/%s/virtual-machine-details', - $dashboard - ); + $url = sprintf('https://grafana.example.com:3000/d-solo/%s/virtual-machine-details', $dashboard); $params = [ 'orgId' => $orgId, @@ -72,7 +66,7 @@ protected function panelUrl($panelId) 'theme' => 'light', 'panelId' => $panelId, 'from' => 1636834044566, - 'to' => 1636843374647, + 'to' => 1636843374647 ]; return $url . '?' . build_query($params); diff --git a/library/Vspheredb/Web/Widget/GuestToolsStatusRenderer.php b/library/Vspheredb/Web/Widget/GuestToolsStatusRenderer.php index 4e9ca26a..455679de 100644 --- a/library/Vspheredb/Web/Widget/GuestToolsStatusRenderer.php +++ b/library/Vspheredb/Web/Widget/GuestToolsStatusRenderer.php @@ -10,38 +10,33 @@ class GuestToolsStatusRenderer extends Html { use Translation; - public function __invoke($state) + public function __invoke($state): Icon { if (is_object($state)) { $state = $state->guest_tools_status; } - switch ($state) { - case 'toolsNotInstalled': - return Icon::create('block', [ - 'class' => 'red', - 'title' => $this->translate('Guest Tools are NOT installed'), - ]); - case 'toolsNotRunning': - return Icon::create('warning-empty', [ - 'class' => 'red', - 'title' => $this->translate('Guest Tools are NOT running'), - ]); - case 'toolsOld': - return Icon::create('thumbs-down', [ - 'class' => 'yellow', - 'title' => $this->translate('Guest Tools are outdated'), - ]); - case 'toolsOk': - return Icon::create('ok', [ - 'class' => 'green', - 'title' => $this->translate('Guest Tools are up to date and running'), - ]); - case null: - default: - return Icon::create('help', [ - 'class' => 'gray', - 'title' => $this->translate('Guest Tools status is now known'), - ]); - } + + return match ($state) { + 'toolsNotInstalled' => Icon::create('block', [ + 'class' => 'red', + 'title' => $this->translate('Guest Tools are NOT installed') + ]), + 'toolsNotRunning' => Icon::create('warning-empty', [ + 'class' => 'red', + 'title' => $this->translate('Guest Tools are NOT running') + ]), + 'toolsOld' => Icon::create('thumbs-down', [ + 'class' => 'yellow', + 'title' => $this->translate('Guest Tools are outdated') + ]), + 'toolsOk' => Icon::create('ok', [ + 'class' => 'green', + 'title' => $this->translate('Guest Tools are up to date and running') + ]), + default => Icon::create('help', [ + 'class' => 'gray', + 'title' => $this->translate('Guest Tools status is now known') + ]) + }; } } diff --git a/library/Vspheredb/Web/Widget/HostHeader.php b/library/Vspheredb/Web/Widget/HostHeader.php index d1f728c8..827286b3 100644 --- a/library/Vspheredb/Web/Widget/HostHeader.php +++ b/library/Vspheredb/Web/Widget/HostHeader.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Widget; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Data\Anonymizer; use Icinga\Module\Vspheredb\DbObject\HostQuickStats; use Icinga\Module\Vspheredb\DbObject\HostSystem; @@ -11,20 +12,15 @@ class HostHeader extends BaseHtmlElement { - /** @var HostSystem */ - protected $host; + protected HostSystem $host; - /** @var HtmlDocument */ - protected $icons; + protected ?HtmlDocument $icons = null; protected $tag = 'div'; - protected $defaultAttributes = [ - 'class' => 'host-header' - ]; + protected $defaultAttributes = ['class' => 'host-header']; - /** @var HostQuickStats */ - protected $quickStats; + protected HostQuickStats $quickStats; public function __construct(HostSystem $host, HostQuickStats $quickStats) { @@ -32,24 +28,20 @@ public function __construct(HostSystem $host, HostQuickStats $quickStats) $this->quickStats = $quickStats; } - public function getIcons() + public function getIcons(): HtmlDocument { - if ($this->icons === null) { - $powerStateRenderer = new PowerStateRenderer(); - $overallStatusRenderer = new OverallStatusRenderer(); - $this->icons = (new HtmlDocument())->add([ - $overallStatusRenderer($this->host->object()->get('overall_status')), - $powerStateRenderer($this->host->get('runtime_power_state')), - ]); - } + $this->icons ??= (new HtmlDocument())->add([ + (new OverallStatusRenderer())($this->host->object()->get('overall_status')), + (new PowerStateRenderer())($this->host->get('runtime_power_state')) + ]); return $this->icons; } /** - * @throws \Icinga\Exception\NotFoundError + * @throws NotFoundError */ - protected function assemble() + protected function assemble(): void { $host = $this->host; $host->object()->set('object_name', Anonymizer::anonymizeString($host->object()->get('object_name'))); @@ -62,14 +54,7 @@ protected function assemble() $this->quickStats->get('overall_memory_usage_mb'), $host->get('hardware_memory_size_mb') ); - $title = Html::tag('h1', [ - $host->object()->get('object_name'), - $this->getIcons() - ]); - $this->add([ - $cpu, - $title, - $mem - ]); + $title = Html::tag('h1', [$host->object()->get('object_name'), $this->getIcons()]); + $this->add([$cpu, $title, $mem]); } } diff --git a/library/Vspheredb/Web/Widget/HostMonitoringInfo.php b/library/Vspheredb/Web/Widget/HostMonitoringInfo.php index 905b9299..5e048240 100644 --- a/library/Vspheredb/Web/Widget/HostMonitoringInfo.php +++ b/library/Vspheredb/Web/Widget/HostMonitoringInfo.php @@ -8,7 +8,6 @@ use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\VCenter; -use ipl\Html\Html; use ipl\Html\HtmlDocument; use ipl\I18n\Translation; @@ -16,14 +15,11 @@ class HostMonitoringInfo extends HtmlDocument { use Translation; - /** @var HostSystem */ - protected $host; + protected HostSystem $host; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; - /** @var mixed */ - protected $info; + protected false|array|null $info = null; /** * HostVirtualizationInfoTable constructor. @@ -36,7 +32,7 @@ public function __construct(HostSystem $host) $this->vCenter = VCenter::load($host->get('vcenter_uuid'), $host->getConnection()); } - protected function assemble() + protected function assemble(): void { if ($info = $this->getInfo()) { $this->prepend(new SubTitle($this->translate('Monitoring'), 'binoculars')); @@ -44,28 +40,24 @@ protected function assemble() } } - public function hasInfo() + public function hasInfo(): bool { return $this->getInfo() !== false; } - protected function getInfo() + protected function getInfo(): false|array { - if ($this->info === null) { - $this->info = $this->prepareInfo(); - } + $this->info ??= $this->prepareInfo(); return $this->info; } /** - * @return array|false + * @return false|array */ - protected function prepareInfo() + protected function prepareInfo(): false|array { - $host = $this->host; - $name = $host->get('host_name'); - $statusRenderer = new IcingaHostStatusRenderer(); + $name = $this->host->get('host_name'); try { // $monitoring = MonitoringConnection::eventuallyLoadForVCenter($this->vCenter); @@ -74,7 +66,7 @@ protected function prepareInfo() $monitoringState = $monitoring->getHostState($name); return [ // TODO: is_acknowledged, is_in_downtime - $statusRenderer($monitoringState->current_state), + (new IcingaHostStatusRenderer())($monitoringState->current_state), ' ', $monitoringState->output, ' ', @@ -85,16 +77,11 @@ protected function prepareInfo() ['class' => 'icon-right-small'] ) ]; - } else { - return false; } + + return false; } catch (Exception $e) { - return [ - Hint::error( - $this->translate('Unable to check monitoring state: %s'), - $e->getMessage() - ) - ]; + return [Hint::error($this->translate('Unable to check monitoring state: %s'), $e->getMessage())]; } } } diff --git a/library/Vspheredb/Web/Widget/IcingaHostStatusRenderer.php b/library/Vspheredb/Web/Widget/IcingaHostStatusRenderer.php index 5a80a670..70da38b5 100644 --- a/library/Vspheredb/Web/Widget/IcingaHostStatusRenderer.php +++ b/library/Vspheredb/Web/Widget/IcingaHostStatusRenderer.php @@ -10,7 +10,7 @@ class IcingaHostStatusRenderer extends Html { use Translation; - public function __invoke($state) + public function __invoke($state): Icon { if (is_object($state)) { $state = $state->overall_status; @@ -18,7 +18,7 @@ public function __invoke($state) return Icon::create('eye', [ 'title' => $this->getStatusDescription($state), - 'class' => [ 'state', $state ] + 'class' => ['state', $state] ]); } @@ -29,13 +29,11 @@ public function __invoke($state) */ protected function getStatusDescription(string $status): string { - $descriptions = [ - 'UP' => $this->translate('This system is up'), + return match ($status) { + 'UP' => $this->translate('This system is up'), 'DOWN' => $this->translate('This system is down'), 'UNREACHABLE' => $this->translate('Unreachable - another device might be responsible for this outage'), - 'PENDING' => $this->translate('Pending - this host has never been checked'), - ]; - - return $descriptions[$status]; + 'PENDING' => $this->translate('Pending - this host has never been checked') + }; } } diff --git a/library/Vspheredb/Web/Widget/Link/Html5UiLink.php b/library/Vspheredb/Web/Widget/Link/Html5UiLink.php index 874aa7af..53857776 100644 --- a/library/Vspheredb/Web/Widget/Link/Html5UiLink.php +++ b/library/Vspheredb/Web/Widget/Link/Html5UiLink.php @@ -19,30 +19,32 @@ class Html5UiLink extends BaseHtmlElement use Translation; public const QUERYSTRING = '/ui/#?extensionId=%s&objectId=%s&navigator=%s'; + public const QUERYSTRING_LEGACY = [ HostSystem::class => '/ui/#/host/%s', - VirtualMachine::class => '/ui/#/host/vms/%s', + VirtualMachine::class => '/ui/#/host/vms/%s' ]; + public const OBJECT_TYPES = [ HostSystem::class => 'HostSystem', - VirtualMachine::class => 'VirtualMachine', + VirtualMachine::class => 'VirtualMachine' ]; // left-hand tree view: public const NAVIGATOR = [ HostSystem::class => 'vsphere.core.viTree.hostsAndClustersView', - VirtualMachine::class => 'vsphere.core.viTree.vmsAndTemplatesView', + VirtualMachine::class => 'vsphere.core.viTree.vmsAndTemplatesView' ]; + public const EXTENSION = [ // Choose main detail view: // $extension = 'vsphere.core.vm.monitor'; // Shows 'Monitor' Tab // $extension = 'vsphere.core.inventory.serverObjectViewsExtension'; HostSystem::class => 'vsphere.core.host.summary', - VirtualMachine::class => 'vsphere.core.vm.summary', + VirtualMachine::class => 'vsphere.core.vm.summary' ]; - /** @var BaseDbObject */ - protected $object; + protected ?BaseDbObject $object = null; public $tag = 'a'; @@ -55,34 +57,28 @@ public function __construct(VCenter $vCenter, BaseDbObject $object, $label) $this->setAttribute('target', '_blank'); // To keep the session } - protected static function prepareUrl(VCenter $vCenter, BaseDbObject $object) + protected static function prepareUrl(VCenter $vCenter, BaseDbObject $object): string { - $url = self::prepareBaseUrl($vCenter); - if (self::isLegacy($vCenter)) { - $url .= self::linkLegacy($object); - } else { - $url .= self::linkHtml5Ui($object, $vCenter); - } - - return $url; + return self::prepareBaseUrl($vCenter) + . (self::isLegacy($vCenter) ? self::linkLegacy($object) : self::linkHtml5Ui($object, $vCenter)); } - protected static function prepareBaseUrl(VCenter $vCenter) + protected static function prepareBaseUrl(VCenter $vCenter): string { return 'https://' . $vCenter->getFirstServer(false)->get('host'); } - protected static function isLegacy(VCenter $vCenter) + protected static function isLegacy(VCenter $vCenter): bool { return version_compare($vCenter->get('version'), '6.7.0', '<'); } - protected static function linkLegacy(BaseDbObject $object) + protected static function linkLegacy(BaseDbObject $object): string { return sprintf(self::pick(self::QUERYSTRING_LEGACY, $object), rawurlencode($object->object()->get('moref'))); } - protected static function linkHtml5Ui(BaseDbObject $object, VCenter $vCenter) + protected static function linkHtml5Ui(BaseDbObject $object, VCenter $vCenter): string { return sprintf( self::QUERYSTRING, @@ -92,7 +88,7 @@ protected static function linkHtml5Ui(BaseDbObject $object, VCenter $vCenter) ); } - protected static function prepareV7ObjectId(VCenter $vCenter, BaseDbObject $object) + protected static function prepareV7ObjectId(VCenter $vCenter, BaseDbObject $object): string { return sprintf( 'urn:vmomi:%s:%s:%s', @@ -102,12 +98,12 @@ protected static function prepareV7ObjectId(VCenter $vCenter, BaseDbObject $obje ); } - protected static function moref(BaseDbObject $object) + protected static function moref(BaseDbObject $object): ?string { return $object->object()->get('moref'); } - protected static function pick(array $list, BaseDbObject $object) + protected static function pick(array $list, BaseDbObject $object): mixed { $class = get_class($object); if (isset($list[$class])) { @@ -117,10 +113,7 @@ protected static function pick(array $list, BaseDbObject $object) throw new RuntimeException("Unable to generate HTML5 UI link for $class"); } - /** - * @throws \Icinga\Exception\NotFoundError - */ - protected function assemble() + protected function assemble(): void { } } diff --git a/library/Vspheredb/Web/Widget/Link/KnowledgeBaseLink.php b/library/Vspheredb/Web/Widget/Link/KnowledgeBaseLink.php index a1b0d0e2..eb696abf 100644 --- a/library/Vspheredb/Web/Widget/Link/KnowledgeBaseLink.php +++ b/library/Vspheredb/Web/Widget/Link/KnowledgeBaseLink.php @@ -13,19 +13,14 @@ class KnowledgeBaseLink extends BaseHtmlElement protected $defaultAttributes = [ 'target' => '_blank', - 'class' => 'vmware_kb_link', + 'class' => 'vmware_kb_link' ]; - public function __construct($id, $title = null, $label = null) + public function __construct(int $id, ?string $title = null, ?string $label = null) { $this->id = $id; - if ($label === null) { - $this->setContent("KB $id"); - } else { - $this->setContent($label); - } - + $this->setContent($label ?? "KB $id"); $this->setAttribute('title', $title); - $this->setAttribute('href', 'https://kb.vmware.com/s/article/' . \rawurlencode($id)); + $this->setAttribute('href', 'https://kb.vmware.com/s/article/' . rawurlencode($id)); } } diff --git a/library/Vspheredb/Web/Widget/Link/MobLink.php b/library/Vspheredb/Web/Widget/Link/MobLink.php index 27f21c05..99cbc11c 100644 --- a/library/Vspheredb/Web/Widget/Link/MobLink.php +++ b/library/Vspheredb/Web/Widget/Link/MobLink.php @@ -7,6 +7,7 @@ use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use Icinga\Module\Vspheredb\DbObject\VCenter; use Icinga\Module\Vspheredb\DbObject\VCenterServer; +use ipl\Html\BaseHtmlElement; use ipl\Html\Html; use ipl\Html\HtmlDocument; use ipl\I18n\Translation; @@ -18,43 +19,34 @@ class MobLink extends HtmlDocument { use Translation; - protected $vCenter; + protected VCenter $vCenter; - protected $label; + protected string $label; - protected $moRef; + protected ?string $moRef = null; - public function __construct(VCenter $vCenter, ?BaseDbObject $object = null, $label = null) + public function __construct(VCenter $vCenter, ?BaseDbObject $object = null, ?string $label = null) { $this->vCenter = $vCenter; if ($object) { $this->moRef = $object->object()->get('moref'); } - if ($label === null) { - if ($this->moRef) { - $this->label = $this->moRef; - } else { - $this->label = 'MOB'; - } - } else { - $this->label = $label; - } + + $this->label = $label ?? ($this->moRef ?: 'MOB'); } - protected function assemble() + protected function assemble(): void { try { $server = $this->vCenter->getFirstServer(false); - if ($this->moRef) { - $this->add($this->createObjectLink($server, $this->moRef, $this->label)); - } else { - $this->add($this->createBaseLink($server, $this->label)); - } - } catch (NotFoundError $e) { + $this->add( + $this->moRef + ? $this->createObjectLink($server, $this->moRef, $this->label) + : $this->createBaseLink($server, $this->label) + ); + } catch (NotFoundError) { $this->add([ - Icon::create('warning-empty', [ - 'class' => 'red' - ]), + Icon::create('warning-empty', ['class' => 'red']), ' ', $this->translate('No related vServer has been configured') ]); @@ -65,39 +57,32 @@ protected function assemble() * @param VCenterServer $server * @param string $moRef * @param string $label - * @return \ipl\Html\BaseHtmlElement + * + * @return BaseHtmlElement */ - protected function createObjectLink(VCenterServer $server, $moRef, $label) + protected function createObjectLink(VCenterServer $server, string $moRef, string $label): BaseHtmlElement { return Html::tag('a', [ - 'href' => sprintf( - 'https://%s/mob/?moid=%s', - $server->get('host'), - rawurlencode($moRef) - ), + 'href' => sprintf('https://%s/mob/?moid=%s', $server->get('host'), rawurlencode($moRef)), 'target' => '_blank', - 'title' => sprintf( - $this->translate('Show "%s" in the Managed Object Browser (MOB)'), - $moRef - ), - 'class' => 'icon-eye', + 'title' => sprintf($this->translate('Show "%s" in the Managed Object Browser (MOB)'), $moRef), + 'class' => 'icon-eye' ], $label); } /** * @param VCenterServer $server * @param string $label - * @return \ipl\Html\BaseHtmlElement + * + * @return BaseHtmlElement */ - protected function createBaseLink(VCenterServer $server, $label) + protected function createBaseLink(VCenterServer $server, $label): BaseHtmlElement { return Html::tag('a', [ - 'href' => sprintf('https://%s/mob/', $server->get('host')), + 'href' => sprintf('https://%s/mob/', $server->get('host')), 'target' => '_blank', - 'title' => sprintf( - $this->translate('Open the Managed Object Browser (MOB)') - ), - 'class' => 'icon-eye', + 'title' => sprintf($this->translate('Open the Managed Object Browser (MOB)')), + 'class' => 'icon-eye' ], $label); } } diff --git a/library/Vspheredb/Web/Widget/Link/VmrcLink.php b/library/Vspheredb/Web/Widget/Link/VmrcLink.php index 1faf3aca..c62aa239 100644 --- a/library/Vspheredb/Web/Widget/Link/VmrcLink.php +++ b/library/Vspheredb/Web/Widget/Link/VmrcLink.php @@ -14,43 +14,32 @@ class VmrcLink extends HtmlDocument { use Translation; - protected $vCenter; + protected VCenter $vCenter; - protected $label; + protected ?string $label; - protected $moRef; + protected ?string $moRef; - public function __construct(VCenter $vCenter, VirtualMachine $vm, $label = null) + public function __construct(VCenter $vCenter, VirtualMachine $vm, ?string $label = null) { $this->vCenter = $vCenter; - if ($label === null) { - $this->label = $vm->object()->get('object_name'); - } else { - $this->label = $label; - } - + $this->label = $label ?? $vm->object()->get('object_name'); $this->moRef = $vm->object()->get('moref'); } - protected function assemble() + protected function assemble(): void { try { $server = $this->vCenter->getFirstServer(false); $this->add(Html::tag('a', [ - 'href' => sprintf( - 'vmrc://%s/?moid=%s', - $server->get('host'), - \rawurlencode($this->moRef) - ), + 'href' => sprintf('vmrc://%s/?moid=%s', $server->get('host'), rawurlencode($this->moRef)), 'target' => '_self', - 'title' => $this->translate('Open VMware Remote Console (VMRC)'), - 'class' => 'icon-host', + 'title' => $this->translate('Open VMware Remote Console (VMRC)'), + 'class' => 'icon-host' ], $this->label)); - } catch (NotFoundError $e) { + } catch (NotFoundError) { $this->add([ - Icon::create('warning-empty', [ - 'class' => 'red' - ]), + Icon::create('warning-empty', ['class' => 'red']), ' ', $this->translate('No related vServer has been configured') ]); diff --git a/library/Vspheredb/Web/Widget/MemoryUsage.php b/library/Vspheredb/Web/Widget/MemoryUsage.php index 7d11bcee..bdeb61bc 100644 --- a/library/Vspheredb/Web/Widget/MemoryUsage.php +++ b/library/Vspheredb/Web/Widget/MemoryUsage.php @@ -7,38 +7,36 @@ class MemoryUsage extends UsageBar { - /** @var int */ - protected $usedHost; + protected int|float|null $usedHost; - protected $colors = [ + protected array $colors = [ 'used' => 'rgba(0, 149, 191, 0.75)', - 'host' => 'rgba(160, 200, 211, 0.75)', + 'host' => 'rgba(160, 200, 211, 0.75)' ]; - protected $formatter = [Format::class, 'mBytes']; - - public function __construct($usedMb, $capacityMb, $usedHostMb = null) + public function __construct(int|float|null $usedMb, int|float|null $capacityMb, int|float|null $usedHostMb = null) { parent::__construct($usedMb, $capacityMb); $this->usedHost = $usedHostMb; + $this->formatter = Format::mBytes(...); } - protected function getLabelUsed() + protected function getLabelUsed(): string { if ($this->usedHost === null) { return parent::getLabelUsed(); - } else { - return sprintf( - '%s: %s (%s: %s)', - $this->translate('Active'), - $this->format($this->used), - $this->translate('Host'), - $this->format($this->usedHost) - ); } + + return sprintf( + '%s: %s (%s: %s)', + $this->translate('Active'), + $this->format($this->used), + $this->translate('Host'), + $this->format($this->usedHost) + ); } - protected function assembleBar(BaseHtmlElement $bar) + protected function assembleBar(BaseHtmlElement $bar): void { parent::assembleBar($bar); if ($this->usedHost !== null && $this->capacity !== null) { diff --git a/library/Vspheredb/Web/Widget/OverallStatusRenderer.php b/library/Vspheredb/Web/Widget/OverallStatusRenderer.php index 49ff4cdb..3e227fa1 100644 --- a/library/Vspheredb/Web/Widget/OverallStatusRenderer.php +++ b/library/Vspheredb/Web/Widget/OverallStatusRenderer.php @@ -13,11 +13,7 @@ class OverallStatusRenderer extends Html public function __invoke($state) { if (is_object($state)) { - if (isset($state->runtime_power_state)) { - $powerState = $state->runtime_power_state; - } else { - $powerState = null; - } + $powerState = $state->runtime_power_state ?? null; $state = $state->overall_status; } else { $powerState = null; @@ -26,13 +22,11 @@ public function __invoke($state) if ($powerState === null || $powerState === 'poweredOn') { return Icon::create($state === 'green' ? 'ok' : 'warning-empty', [ 'title' => $this->getStatusDescription($state), - 'class' => [ 'state', $state ] + 'class' => ['state', $state] ]); - } else { - $powerInfo = new PowerStateRenderer(); - - return $powerInfo($powerState); } + + return (new PowerStateRenderer())($powerState); } /** @@ -42,13 +36,11 @@ public function __invoke($state) */ protected function getStatusDescription(string $status): string { - $descriptions = [ + return match ($status) { 'gray' => $this->translate('Gray - status is unknown'), 'green' => $this->translate('Green - everything is fine'), 'yellow' => $this->translate('Yellow - there are warnings'), - 'red' => $this->translate('Red - there is a problem'), - ]; - - return $descriptions[$status]; + 'red' => $this->translate('Red - there is a problem') + }; } } diff --git a/library/Vspheredb/Web/Widget/PowerStateRenderer.php b/library/Vspheredb/Web/Widget/PowerStateRenderer.php index 0220be8e..71eef67c 100644 --- a/library/Vspheredb/Web/Widget/PowerStateRenderer.php +++ b/library/Vspheredb/Web/Widget/PowerStateRenderer.php @@ -15,9 +15,10 @@ public function __invoke($state) if (is_object($state)) { $state = $state->runtime_power_state; } + return Icon::create('off', [ 'title' => $this->getPowerStateDescription($state), - 'class' => [ 'state', $state ] + 'class' => ['state', $state] ]); } @@ -28,18 +29,20 @@ public function __invoke($state) */ public function getPowerStateDescription(string $state): string { - $descriptions = [ + $result = match ($state) { 'poweredOn' => $this->translate('Powered on'), 'poweredOff' => $this->translate('Powered off'), 'suspended' => $this->translate('Suspended'), 'standby' => $this->translate('Standby'), 'unknown' => $this->translate('Power state is unknown (disconnected?)'), - ]; + default => null + }; - if (! array_key_exists($state, $descriptions)) { + if ($result === null) { var_dump($state); return 'nono'; } - return $descriptions[$state]; + + return $result; } } diff --git a/library/Vspheredb/Web/Widget/Renderer/GuestToolsVersionRenderer.php b/library/Vspheredb/Web/Widget/Renderer/GuestToolsVersionRenderer.php index 2dc5f553..e7dd0617 100644 --- a/library/Vspheredb/Web/Widget/Renderer/GuestToolsVersionRenderer.php +++ b/library/Vspheredb/Web/Widget/Renderer/GuestToolsVersionRenderer.php @@ -6,17 +6,17 @@ class GuestToolsVersionRenderer { public function __invoke($version) { - if (\is_object($version)) { + if (is_object($version)) { $version = $version->guest_tools_version; } if ($version === null || $version === '0') { return '-'; } if ( - \preg_match('/^([89])(\d{1})(\d{2})$/', $version, $m) - || \preg_match('/^(1\d)(\d{1})(\d{2})$/', $version, $m) + preg_match('/^([89])(\d{1})(\d{2})$/', $version, $m) + || preg_match('/^(1\d)(\d{1})(\d{2})$/', $version, $m) ) { - $version = \sprintf('%d.%d.%d', $m[1], $m[2], $m[3]); + $version = sprintf('%d.%d.%d', $m[1], $m[2], $m[3]); } return $version; diff --git a/library/Vspheredb/Web/Widget/Renderer/PathToObjectRenderer.php b/library/Vspheredb/Web/Widget/Renderer/PathToObjectRenderer.php index 1ab91d4c..b96a15a2 100644 --- a/library/Vspheredb/Web/Widget/Renderer/PathToObjectRenderer.php +++ b/library/Vspheredb/Web/Widget/Renderer/PathToObjectRenderer.php @@ -4,6 +4,7 @@ use gipfl\IcingaWeb2\Link; use Icinga\Module\Vspheredb\Data\Anonymizer; +use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use Icinga\Module\Vspheredb\DbObject\Datastore; use Icinga\Module\Vspheredb\DbObject\HostSystem; @@ -12,35 +13,32 @@ use Icinga\Module\Vspheredb\Util; use InvalidArgumentException; use ipl\Html\Html; +use ipl\Html\HtmlElement; class PathToObjectRenderer { - protected $classLinkMap = [ + protected array $classLinkMap = [ VirtualMachine::class => 'vspheredb/vms', HostSystem::class => 'vspheredb/hosts', - Datastore::class => 'vspheredb/datastores', + Datastore::class => 'vspheredb/datastores' ]; - public static function render(BaseDbObject $object) + public static function render(BaseDbObject $object): HtmlElement { - $instance = new static(); - - return $instance($object); + return (new static())($object); } - public function __invoke(BaseDbObject $object) + public function __invoke(BaseDbObject $object): HtmlElement { $uuid = $object->get('uuid'); - /** @var \Icinga\Module\Vspheredb\Db $connection */ + /** @var Db $connection */ $connection = $object->getConnection(); $lookup = new PathLookup($connection->getDbAdapter()); - $class = \get_class($object); + $class = get_class($object); if (isset($this->classLinkMap[$class])) { $baseUrl = $this->classLinkMap[$class]; } else { - throw new InvalidArgumentException( - "PathToObjectRenderer doesn't support $class" - ); + throw new InvalidArgumentException("PathToObjectRenderer doesn't support $class"); } $path = Html::tag('span', ['class' => 'dc-path']); $parts = []; @@ -55,8 +53,7 @@ public function __invoke(BaseDbObject $object) ['data-base-target' => '_main'] ); } - $path->add($parts); - return $path; + return $path->add($parts); } } diff --git a/library/Vspheredb/Web/Widget/ResourceUsage.php b/library/Vspheredb/Web/Widget/ResourceUsage.php index 1ed9cc63..acc1471a 100644 --- a/library/Vspheredb/Web/Widget/ResourceUsage.php +++ b/library/Vspheredb/Web/Widget/ResourceUsage.php @@ -3,18 +3,25 @@ namespace Icinga\Module\Vspheredb\Web\Widget; use gipfl\Json\JsonSerialization; +use ReturnTypeWillChange; class ResourceUsage implements JsonSerialization { - public $usedMhz; - public $totalMhz; - public $usedMb; - public $totalMb; - public $dsCapacity; - public $dsFreeSpace; - public $dsUncommitted; - - public static function fromSerialization($any) + public ?int $usedMhz = null; + + public ?int $totalMhz = null; + + public ?int $usedMb = null; + + public ?int $totalMb = null; + + public ?int $dsCapacity = null; + + public ?int $dsFreeSpace = null; + + public ?int $dsUncommitted = null; + + public static function fromSerialization($any): static { $self = new static(); $self->usedMhz = $any->used_mhz; @@ -28,8 +35,8 @@ public static function fromSerialization($any) return $self; } - #[\ReturnTypeWillChange] - public function jsonSerialize() + #[ReturnTypeWillChange] + public function jsonSerialize(): array { return [ 'used_mhz' => $this->usedMhz, @@ -38,7 +45,7 @@ public function jsonSerialize() 'total_mb' => $this->totalMb, 'ds_capacity' => $this->dsCapacity, 'ds_free_space' => $this->dsFreeSpace, - 'ds_uncommitted' => $this->dsUncommitted, + 'ds_uncommitted' => $this->dsUncommitted ]; } } diff --git a/library/Vspheredb/Web/Widget/ResourceUsageLoader.php b/library/Vspheredb/Web/Widget/ResourceUsageLoader.php index 511dce1c..2a5cff60 100644 --- a/library/Vspheredb/Web/Widget/ResourceUsageLoader.php +++ b/library/Vspheredb/Web/Widget/ResourceUsageLoader.php @@ -5,62 +5,59 @@ use gipfl\ZfDb\Adapter\Adapter; use Icinga\Module\Vspheredb\PathLookup; use Ramsey\Uuid\UuidInterface; +use Zend_Db_Adapter_Abstract; class ResourceUsageLoader { - /** @var UuidInterface */ - protected $vCenterUuid; + protected ?UuidInterface $vCenterUuid = null; - /** @var Adapter|\Zend_Db_Adapter_Abstract */ - protected $db; + protected Adapter|Zend_Db_Adapter_Abstract $db; - /** @var array */ - protected $parentUuids; + protected ?array $parentUuids = null; /** - * @param Adapter|\Zend_Db_Adapter_Abstract $db + * @param Adapter|Zend_Db_Adapter_Abstract $db */ - public function __construct($db) + public function __construct(Adapter|Zend_Db_Adapter_Abstract $db) { $this->db = $db; } /** - * @param UuidInterface|null $vCenterUuid + * @param ?UuidInterface $vCenterUuid * @return $this */ - public function filterVCenterUuid(?UuidInterface $vCenterUuid = null) + public function filterVCenterUuid(?UuidInterface $vCenterUuid = null): static { $this->vCenterUuid = $vCenterUuid; return $this; } - public function filterByParentUuid($uuid) + public function filterByParentUuid(string $uuid): static { - $lookup = new PathLookup($this->db); - $this->parentUuids = $lookup->listFoldersBelongingTo($uuid); + $this->parentUuids = (new PathLookup($this->db))->listFoldersBelongingTo($uuid); return $this; } - public function fetch() + public function fetch(): ResourceUsage { $db = $this->db; - $query = $db->select()->from(['h' => 'host_system'], [ - 'used_mhz' => 'SUM(hqs.overall_cpu_usage)', - 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)', - 'used_mb' => 'SUM(hqs.overall_memory_usage_mb)', - 'total_mb' => 'SUM(h.hardware_memory_size_mb)', - ])->join([ - 'hqs' => 'host_quick_stats' - ], 'h.uuid = hqs.uuid', []); + $query = $db->select() + ->from(['h' => 'host_system'], [ + 'used_mhz' => 'SUM(hqs.overall_cpu_usage)', + 'total_mhz' => 'SUM(h.hardware_cpu_cores * h.hardware_cpu_mhz)', + 'used_mb' => 'SUM(hqs.overall_memory_usage_mb)', + 'total_mb' => 'SUM(h.hardware_memory_size_mb)' + ]) + ->join(['hqs' => 'host_quick_stats'], 'h.uuid = hqs.uuid', []); $compute = $db->fetchRow($this->applyFilters($query, 'h')); $query = $db->select()->from(['ds' => 'datastore'], [ 'ds_capacity' => 'SUM(ds.capacity)', 'ds_free_space' => 'SUM(ds.free_space)', - 'ds_uncommitted' => 'SUM(ds.uncommitted)', + 'ds_uncommitted' => 'SUM(ds.uncommitted)' ]); $storage = $db->fetchRow($this->applyFilters($query, 'ds')); diff --git a/library/Vspheredb/Web/Widget/ServiceTagRenderer.php b/library/Vspheredb/Web/Widget/ServiceTagRenderer.php index 6b644aaa..fbc4f96c 100644 --- a/library/Vspheredb/Web/Widget/ServiceTagRenderer.php +++ b/library/Vspheredb/Web/Widget/ServiceTagRenderer.php @@ -5,50 +5,48 @@ use gipfl\IcingaWeb2\Icon; use Icinga\Module\Vspheredb\DbObject\HostSystem; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\I18n\Translation; class ServiceTagRenderer extends Html { use Translation; - public function __invoke($host) + public function __invoke($host): HtmlElement|string|null { - if (! $host instanceof HostSystem) { + if (! $host instanceof HostSystem) { $host = HostSystem::create([ 'service_tag' => $host->service_tag, - 'sysinfo_vendor' => $host->sysinfo_vendor, + 'sysinfo_vendor' => $host->sysinfo_vendor ]); } return $this->getFormattedServiceTag($host); } - protected function getFormattedServiceTag(HostSystem $host) + protected function getFormattedServiceTag(HostSystem $host): HtmlElement|string|null { if ($host->get('sysinfo_vendor') === 'Dell Inc.') { return $this->linkToDellSupport($host->get('service_tag')); - } else { - return $host->get('service_tag'); } + + return $host->get('service_tag'); } - protected function linkToDellSupport($serviceTag) + protected function linkToDellSupport(?string $serviceTag): ?HtmlElement { if ($serviceTag === null) { return null; } - $urlPattern = 'http://www.dell.com/support/home/product-support/servicetag/%s/drivers'; - - $url = sprintf( - $urlPattern, - strtolower($serviceTag) - ); return Html::tag('a', [ - 'href' => $url, - 'target' => '_blank', - 'title' => $this->translate('Dell Support Page'), - 'rel' => 'noreferrer' + 'href' => sprintf( + 'http://www.dell.com/support/home/product-support/servicetag/%s/drivers', + strtolower($serviceTag) + ), + 'target' => '_blank', + 'title' => $this->translate('Dell Support Page'), + 'rel' => 'noreferrer' ], [Icon::create('forward'), $serviceTag]); } } diff --git a/library/Vspheredb/Web/Widget/SimpleUsageBar.php b/library/Vspheredb/Web/Widget/SimpleUsageBar.php index eb6e46ce..ab6b3e40 100644 --- a/library/Vspheredb/Web/Widget/SimpleUsageBar.php +++ b/library/Vspheredb/Web/Widget/SimpleUsageBar.php @@ -15,23 +15,20 @@ class SimpleUsageBar extends BaseHtmlElement 'data-base-target' => '_next' ]; - /** @var int */ - protected $used; + protected int $used; - /** @var int */ - protected $total; + protected int $total; - /** @var string */ - protected $title; + protected string $title; - public function __construct($used, $total, $title) + public function __construct(int $used, int $total, string $title) { $this->used = $used; $this->total = $total; $this->title = $title; } - protected function assemble() + protected function assemble(): void { $usedPercent = $this->used / $this->total; diff --git a/library/Vspheredb/Web/Widget/SubTitle.php b/library/Vspheredb/Web/Widget/SubTitle.php index 397cec39..9e78f650 100644 --- a/library/Vspheredb/Web/Widget/SubTitle.php +++ b/library/Vspheredb/Web/Widget/SubTitle.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Widget; +use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; class SubTitle extends BaseHtmlElement @@ -10,14 +11,15 @@ class SubTitle extends BaseHtmlElement /** * SubTitle constructor. + * * @param string $title - * @param string|null $icon + * @param ?string $icon */ - public function __construct($title, $icon = null) + public function __construct(string $title, ?string $icon = null) { $this->setContent($title); if ($icon !== null) { - $this->addAttributes(['class' => "icon-$icon"]); + $this->addAttributes(Attributes::create(['class' => "icon-$icon"])); } } } diff --git a/library/Vspheredb/Web/Widget/Summaries.php b/library/Vspheredb/Web/Widget/Summaries.php index 31e8a2a5..0a6e0920 100644 --- a/library/Vspheredb/Web/Widget/Summaries.php +++ b/library/Vspheredb/Web/Widget/Summaries.php @@ -4,13 +4,14 @@ use gipfl\IcingaWeb2\Icon; use gipfl\IcingaWeb2\Link; -use ipl\I18n\Translation; use gipfl\IcingaWeb2\Url; use Icinga\Module\Vspheredb\Db; use Icinga\Module\Vspheredb\Web\Table\Objects\ObjectsTable; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use ipl\I18n\Translation; use RuntimeException; +use Zend_Db_Adapter_Abstract; use Zend_Db_Select as ZfSelect; use Zend_Db_Select_Exception; @@ -20,22 +21,17 @@ class Summaries extends BaseHtmlElement protected $tag = 'div'; - protected $defaultAttributes = [ - 'class' => 'object-summaries', - ]; + protected $defaultAttributes = ['class' => 'object-summaries']; - /** @var \Zend_Db_Select */ - protected $query; + protected ?ZfSelect $query = null; - protected $stats; + protected ?object $stats = null; - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; - /** @var Url */ - protected $baseUrl; + protected Url $baseUrl; - protected $wantsPowerState = false; + protected bool $wantsPowerState = false; /** * Summaries constructor. @@ -56,9 +52,10 @@ public function __construct(ObjectsTable $table, Db $db, Url $baseUrl) /** * @param ObjectsTable $table - * @throws \Zend_Db_Select_Exception + * + * @throws Zend_Db_Select_Exception */ - protected function setTable(ObjectsTable $table) + protected function setTable(ObjectsTable $table): void { $this->setQueryFromTable($table); $this->addColumn('o.overall_status', ['gray', 'green', 'yellow', 'red']); @@ -72,7 +69,7 @@ protected function setTable(ObjectsTable $table) 'poweredOff', 'unknown', 'standby', - 'suspended', + 'suspended' ]); $this->wantsPowerState = true; @@ -81,7 +78,7 @@ protected function setTable(ObjectsTable $table) $this->applyUrlFilters($table); } - protected function applyUrlFilters(ObjectsTable $table) + protected function applyUrlFilters(ObjectsTable $table): void { foreach ($this->baseUrl->getParams()->toArray() as $param) { if ($table->hasColumn($param[0])) { @@ -102,9 +99,10 @@ protected function applyUrlFilters(ObjectsTable $table) /** * @param ObjectsTable $table - * @throws \Zend_Db_Select_Exception + * + * @throws Zend_Db_Select_Exception */ - protected function setQueryFromTable(ObjectsTable $table) + protected function setQueryFromTable(ObjectsTable $table): void { $query = clone($table->getQuery()); $query->reset(ZfSelect::LIMIT_COUNT); @@ -114,9 +112,7 @@ protected function setQueryFromTable(ObjectsTable $table) // This works, but is not as general-purpose as it should be if (count($query->getPart(ZfSelect::GROUP)) > 0) { - $query = $query->getAdapter()->select()->from([ - 'o' => $query->columns('o.overall_status') - ], []); + $query = $query->getAdapter()->select()->from(['o' => $query->columns('o.overall_status')], []); } $this->query = $query; @@ -125,9 +121,10 @@ protected function setQueryFromTable(ObjectsTable $table) /** * @param $column * @param $variants - * @throws \Zend_Db_Select_Exception + * + * @throws Zend_Db_Select_Exception */ - protected function addColumn($column, $variants) + protected function addColumn($column, $variants): void { $columns = []; foreach ($variants as $value) { @@ -136,26 +133,22 @@ protected function addColumn($column, $variants) $this->query->columns($columns); } - protected function makeColumnAlias($column) + protected function makeColumnAlias($column): string { return 'cnt_' . strtolower(preg_replace('/^.+?\./', '', $column)); } - protected function countFiltered($column, $value) + protected function countFiltered($column, $value): string { return "SUM(CASE WHEN $column = '$value' THEN 1 ELSE 0 END)"; } protected function stats() { - if ($this->stats === null) { - $this->stats = $this->db->fetchRow($this->query); - } - - return $this->stats; + return $this->stats ??= $this->db->fetchRow($this->query); } - public function addPowerState() + public function addPowerState(): static { return $this; } @@ -168,8 +161,7 @@ public function addPowerState() */ protected function createSummaryLink(string $value, string $property): ?Link { - $stats = $this->stats(); - $count = (int) $stats->{"cnt_$value"}; + $count = (int) $this->stats()->{"cnt_$value"}; if ($count === 0) { return null; @@ -205,16 +197,11 @@ protected function addSummaryLinks(string $column, array $variants): void $this->add($span); } - protected function assemble() + protected function assemble(): void { $this->setSeparator(' '); $this->add([Icon::create('ok'), $this->translate('Status') . ': ']); - $this->addSummaryLinks('overall_status', [ - 'red', - 'yellow', - 'gray', - 'green' - ]); + $this->addSummaryLinks('overall_status', ['red', 'yellow', 'gray', 'green']); if ($this->wantsPowerState) { $this->add([Icon::create('off'), $this->translate('Power') . ': ']); $this->addSummaryLinks('runtime_power_state', [ diff --git a/library/Vspheredb/Web/Widget/TaggingDetails.php b/library/Vspheredb/Web/Widget/TaggingDetails.php index ae04e6e5..336a615b 100644 --- a/library/Vspheredb/Web/Widget/TaggingDetails.php +++ b/library/Vspheredb/Web/Widget/TaggingDetails.php @@ -4,13 +4,11 @@ use gipfl\Json\JsonString; use gipfl\Web\Table\NameValueTable; -use Icinga\Module\Vspheredb\DbObject\BaseDbObject; use Icinga\Module\Vspheredb\DbObject\HostSystem; use Icinga\Module\Vspheredb\DbObject\TaggingCategory; use Icinga\Module\Vspheredb\DbObject\TaggingObjectTag; use Icinga\Module\Vspheredb\DbObject\TaggingTag; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; -use InvalidArgumentException; use ipl\Html\Html; use ipl\Html\HtmlDocument; use ipl\I18n\Translation; @@ -20,29 +18,21 @@ class TaggingDetails extends HtmlDocument { use Translation; - /** @var HostSystem|VirtualMachine */ - protected $object; + protected HostSystem|VirtualMachine $object; - /** - * @var TaggingTag[] - */ - protected $tags; - /** - * @var TaggingCategory[] - */ - protected $categories; + /** @var TaggingTag[] */ + protected array $tags; - public function __construct(BaseDbObject $object) + /** @var TaggingCategory[] */ + protected array $categories; + + public function __construct(HostSystem|VirtualMachine $object) { - if (! $object instanceof HostSystem && ! $object instanceof VirtualMachine) { - throw new InvalidArgumentException( - 'HostSystem or VirtualMachine expected, got ' . \get_class($object) - ); - } $this->object = $object; $connection = $object->getConnection(); $db = $connection->getDbAdapter(); - $where = $db->select()->from(['tt' => TaggingTag::TABLE], 'tt.*') + $where = $db->select() + ->from(['tt' => TaggingTag::TABLE], 'tt.*') ->join(['tot' => TaggingObjectTag::TABLE], 'tot.tag_uuid = tt.uuid', []) ->where('tot.object_uuid = ?', $object->get('uuid')) ->order('tt.name'); @@ -58,7 +48,7 @@ public function __construct(BaseDbObject $object) // $this->setDemoTags(); } - protected function assemble() + protected function assemble(): void { $this->prepend(new SubTitle($this->translate('Tags'), 'tags')); $internal = JsonString::decode($this->object->object()->get('tags')); @@ -67,17 +57,14 @@ protected function assemble() if (empty($this->tags) && empty($internal)) { $this->add($this->translate('No tags been defined')); + return; } $table = NameValueTable::create(); $this->add($table); foreach ($this->categories as $category) { - if ($category->cardinalityIsSingle()) { - $parent = new HtmlDocument(); - } else { - $parent = Html::tag('ul'); - } + $parent = $category->cardinalityIsSingle() ? new HtmlDocument() : Html::tag('ul'); foreach ($this->tags as $tag) { if ($tag->get('category_uuid') === $category->get('uuid')) { $tagName = $tag->get('name'); @@ -85,11 +72,7 @@ protected function assemble() if ($description !== null && $description !== '') { $tagName = Html::tag('span', ['class' => 'hover-hint', 'title' => $description], $tagName); } - if ($category->cardinalityIsSingle()) { - $parent->add($tagName); - } else { - $parent->add(Html::tag('li', $tagName)); - } + $parent->add($category->cardinalityIsSingle() ? $tagName : Html::tag('li', $tagName)); } } $table->addNameValueRow($category->get('name'), $parent); @@ -105,13 +88,14 @@ protected function assemble() } // Other example, for DistributedVirtualPortgroup: has "SYSTEM/DVS.UPLINKPG" for dvUplink Portgroup } - $table->addNameValueRow([ - Html::tag('i', $this->translate('Internal')), - ], Html::tag('ul', Html::wrapEach($internal, 'li'))); + $table->addNameValueRow( + [Html::tag('i', $this->translate('Internal'))], + Html::tag('ul', Html::wrapEach($internal, 'li')) + ); } } - protected function setDemoTags() + protected function setDemoTags(): void { $uuidCat1 = Uuid::fromString('a09657cb-0c0f-4c32-93de-f98a1a3e5229')->getBytes(); $uuidCat2 = Uuid::fromString('b2272134-f552-44b4-b1c9-56fdb8d9b80b')->getBytes(); @@ -119,28 +103,28 @@ protected function setDemoTags() TaggingTag::create([ 'category_uuid' => $uuidCat1, 'name' => 'Prod', - 'description' => 'Our production environment', + 'description' => 'Our production environment' ]), TaggingTag::create([ 'category_uuid' => $uuidCat2, - 'name' => 'Another Corp.', + 'name' => 'Another Corp.' ]), TaggingTag::create([ 'category_uuid' => $uuidCat2, - 'name' => 'Contoso Inc', - ]), + 'name' => 'Contoso Inc' + ]) ]; $this->categories = [ $uuidCat1 => TaggingCategory::create([ 'uuid' => $uuidCat1, 'name' => 'Environment', - 'cardinality' => 'SINGLE', + 'cardinality' => 'SINGLE' ]), $uuidCat2 => TaggingCategory::create([ 'uuid' => $uuidCat2, 'name' => 'Customer', - 'cardinality' => 'MULTIPLE', - ]), + 'cardinality' => 'MULTIPLE' + ]) ]; } } diff --git a/library/Vspheredb/Web/Widget/ToggleFlagList.php b/library/Vspheredb/Web/Widget/ToggleFlagList.php index b183edb4..c2a50e03 100644 --- a/library/Vspheredb/Web/Widget/ToggleFlagList.php +++ b/library/Vspheredb/Web/Widget/ToggleFlagList.php @@ -6,6 +6,7 @@ use gipfl\IcingaWeb2\Url; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\I18n\Translation; use Zend_Db_Select as DbSelect; @@ -15,29 +16,25 @@ abstract class ToggleFlagList extends BaseHtmlElement protected $tag = 'li'; - /** @var Url */ - private $url; + private Url $url; - /** @var string */ - private $param; + private string $param; - /** @var DbSelect|null */ - private $originalQuery; + private ?DbSelect $originalQuery = null; - /** @var DbSelect|null */ - private $query; + private ?DbSelect $query = null; - protected $iconMain = 'angle-double-down'; + protected string $iconMain = 'angle-double-down'; - protected $iconModified = 'flapping'; + protected string $iconModified = 'flapping'; - public function __construct(Url $url, $param) + public function __construct(Url $url, string $param) { $this->url = $url; $this->param = $param; } - public function applyToQuery(DbSelect $query) + public function applyToQuery(DbSelect $query): static { $this->originalQuery = $query; $this->query = clone $query; @@ -45,16 +42,16 @@ public function applyToQuery(DbSelect $query) return $this; } - abstract protected function getListLabel(); + abstract protected function getListLabel(): string; - abstract protected function getOptions(); + abstract protected function getOptions(): array; - protected function getDefaultSelection() + protected function getDefaultSelection(): array { - return \array_keys($this->getOptions()); + return array_keys($this->getOptions()); } - protected function setEnabled($enabled, $all) + protected function setEnabled(array $enabled, array $all): void { if ($all === $enabled) { // No need to extend the query with useless overhead @@ -65,24 +62,18 @@ protected function setEnabled($enabled, $all) if (empty($enabled)) { $this->originalQuery->where('1 = 0'); } else { - $this->originalQuery->where( - $this->param . ' IN (?)', - $enabled - ); + $this->originalQuery->where($this->param . ' IN (?)', $enabled); } } } - protected function assemble() + protected function assemble(): void { $link = Link::create($this->getListLabel(), '#', null, ['class' => 'icon-' . $this->iconMain]); - $this->add([ - $link, - $this->createLinkList($this->toggleColumnsOptions($link)) - ]); + $this->add([$link, $this->createLinkList($this->toggleColumnsOptions($link))]); } - protected function toggleColumnsOptions(Link $mainLink) + protected function toggleColumnsOptions(Link $mainLink): array { $default = $this->getDefaultSelection(); $links = []; @@ -93,10 +84,7 @@ protected function toggleColumnsOptions(Link $mainLink) if ($enabled === null) { $enabled = $default; } else { - $mainLink->getAttributes()->set( - 'class', - 'modified icon-' . $this->iconModified - ); + $mainLink->getAttributes()->set('class', 'modified icon-' . $this->iconModified); $links[] = $this->geturlReset(); $enabled = $this->splitUrlOptions($enabled); } @@ -105,23 +93,23 @@ protected function toggleColumnsOptions(Link $mainLink) $disabled = []; foreach ($this->getOptions() as $option => $label) { $all[] = $option; - if (\in_array($option, $enabled)) { - $urlOptions = \array_diff($enabled, [$option]); + if (in_array($option, $enabled)) { + $urlOptions = array_diff($enabled, [$option]); $icon = 'check'; $title = $this->translate('Click to hide'); } else { $disabled[] = $option; - $urlOptions = \array_merge($enabled, [$option]); + $urlOptions = array_merge($enabled, [$option]); $icon = 'plus'; $title = $this->translate('Click to show'); } $links[] = Link::create($label, $this->getUrlWithOptions($urlOptions), null, [ 'class' => "icon-$icon", - 'title' => $title, + 'title' => $title ]); } if (! empty($disabled) && $all !== $default) { - \array_unshift($links, Link::create( + array_unshift($links, Link::create( $this->translate('All'), $url->with($param, $this->joinUrlOptions($all)), null, @@ -138,7 +126,7 @@ protected function toggleColumnsOptions(Link $mainLink) return $links; } - protected function geturlReset() + protected function geturlReset(): Link { return Link::create( $this->translate('Reset'), @@ -148,22 +136,22 @@ protected function geturlReset() ); } - protected function getUrlWithOptions($options) + protected function getUrlWithOptions($options): Url { return $this->url->with($this->param, $this->joinUrlOptions($options)); } - protected function joinUrlOptions($value) + protected function joinUrlOptions($value): string { - return \implode(',', $value); + return implode(',', $value); } - protected function splitUrlOptions($value) + protected function splitUrlOptions($value): array { - return \preg_split('/,/', $value, -1, PREG_SPLIT_NO_EMPTY); + return preg_split('/,/', $value, -1, PREG_SPLIT_NO_EMPTY); } - protected function createLinkList($links) + protected function createLinkList($links): HtmlElement { $ul = Html::tag('ul'); diff --git a/library/Vspheredb/Web/Widget/ToggleTableColumns.php b/library/Vspheredb/Web/Widget/ToggleTableColumns.php index 6a50ab68..0b350b0b 100644 --- a/library/Vspheredb/Web/Widget/ToggleTableColumns.php +++ b/library/Vspheredb/Web/Widget/ToggleTableColumns.php @@ -7,12 +7,11 @@ class ToggleTableColumns extends ToggleFlagList { - /** @var BaseTable */ - protected $table; + protected BaseTable $table; - protected $iconMain = 'th-list'; + protected string $iconMain = 'th-list'; - protected $iconModified = 'th-list'; + protected string $iconModified = 'th-list'; public function __construct(BaseTable $table, Url $url) { @@ -20,23 +19,23 @@ public function __construct(BaseTable $table, Url $url) $this->table = $table; } - protected function getListLabel() + protected function getListLabel(): string { return ''; // return $this->translate('Columns'); } - protected function getDefaultSelection() + protected function getDefaultSelection(): array { return $this->table->getChosenColumnNames(); } - protected function setEnabled($enabled, $all) + protected function setEnabled(array $enabled, array $all): void { $this->table->chooseColumns($enabled); } - protected function getOptions() + protected function getOptions(): array { $options = []; foreach ($this->table->getAvailableColumns() as $column) { diff --git a/library/Vspheredb/Web/Widget/UsageBar.php b/library/Vspheredb/Web/Widget/UsageBar.php index 86bc2b61..eb08e439 100644 --- a/library/Vspheredb/Web/Widget/UsageBar.php +++ b/library/Vspheredb/Web/Widget/UsageBar.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Vspheredb\Web\Widget; +use Closure; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; use ipl\I18n\Translation; @@ -13,67 +14,53 @@ class UsageBar extends BaseHtmlElement protected $tag = 'div'; - protected $defaultAttributes = [ - 'class' => 'resource-usage', - ]; + protected $defaultAttributes = ['class' => 'resource-usage']; - protected $colors = [ - 'used' => 'rgba(0, 149, 191, 0.75)', - ]; + protected array $colors = ['used' => 'rgba(0, 149, 191, 0.75)']; - /** @var int */ - protected $used; + protected int|float|null $used; - /** @var int */ - protected $capacity; + protected int|float|null $capacity; - protected $formatter; + protected ?Closure $formatter = null; - protected $showLabels = true; + protected bool $showLabels = true; - public function __construct($used, $capacity) + public function __construct(int|float|null $used, int|float|null $capacity) { $this->used = $used; $this->capacity = $capacity; } /** - * @param $percent - * @param $title + * @param float|int $percent + * @param string $title * @param string $color * * @return array */ - protected function makeSegment($percent, $title, string $color = 'used'): array + protected function makeSegment(float|int $percent, string $title, string $color = 'used'): array { - if (isset($this->colors[$color])) { - $color = $this->colors[$color]; - } - - $usage = Html::tag('div', [ - 'class' => 'usage', - 'title' => $title - ]); - + $usage = Html::tag('div', ['class' => 'usage', 'title' => $title]); $style = (new StyleWithNonce()) ->setModule('vspheredb') ->addFor($usage, [ - 'width' => sprintf('%0.3F%%', $percent * 100), - 'background-color' => $color, + 'width' => sprintf('%0.3F%%', $percent * 100), + 'background-color' => $this->colors[$color] ?? $color ]); return [$usage, $style]; } - public function setFormatter($callback) + public function setFormatter($callback): static { $this->formatter = $callback; return $this; } - public function showLabels($show = true) + public function showLabels($show = true): static { $this->showLabels = (bool) $show; return $this; @@ -83,14 +70,12 @@ protected function format($value) { if ($this->formatter === null) { return $value; - } else { - $formatter = $this->formatter; - - return $formatter($value); } + + return ($this->formatter)($value); } - protected function getTitleUsed() + protected function getTitleUsed(): string { return sprintf( $this->translate('Used: %s of %s (%.2F%%)'), @@ -100,29 +85,26 @@ protected function getTitleUsed() ); } - protected function getLabelUsed() + protected function getLabelUsed(): string { return sprintf($this->translate('%s used'), $this->format($this->used)); } - protected function getLabelCapacity() + protected function getLabelCapacity(): string { return $this->translate('Capacity') . ': ' . $this->format($this->capacity); } - protected function assembleBar(BaseHtmlElement $bar) + protected function assembleBar(BaseHtmlElement $bar): void { if ($this->capacity !== null && $this->capacity !== 0) { $bar->add($this->makeSegment($this->used / $this->capacity, $this->getTitleUsed())); } } - protected function assemble() + protected function assemble(): void { - $usage = Html::tag('div', [ - 'class' => 'usage-bar', - 'data-base-target' => '_next', - ]); + $usage = Html::tag('div', ['class' => 'usage-bar', 'data-base-target' => '_next']); $this->assembleBar($usage); $this->add($usage); if ($this->showLabels) { @@ -130,16 +112,12 @@ protected function assemble() } } - protected function addLabels() + protected function addLabels(): void { $this->add([ - Html::tag('span', [ - 'class' => 'usage-used' - ], $this->getLabelUsed()), + Html::tag('span', ['class' => 'usage-used'], $this->getLabelUsed()), ' ', - Html::tag('span', [ - 'class' => 'usage-capacity' - ], $this->getLabelCapacity()), + Html::tag('span', ['class' => 'usage-capacity'], $this->getLabelCapacity()) ]); } } diff --git a/library/Vspheredb/Web/Widget/UsageSummary.php b/library/Vspheredb/Web/Widget/UsageSummary.php index c8df3cea..1d64c67a 100644 --- a/library/Vspheredb/Web/Widget/UsageSummary.php +++ b/library/Vspheredb/Web/Widget/UsageSummary.php @@ -13,9 +13,7 @@ class UsageSummary extends BaseHtmlElement protected $tag = 'div'; - protected $defaultAttributes = [ - 'class' => 'usage-summary-widget' - ]; + protected $defaultAttributes = ['class' => 'usage-summary-widget']; public function __construct(ResourceUsage $usate) { @@ -27,13 +25,13 @@ public function __construct(ResourceUsage $usate) Html::tag('div', $attr, $this->smallUnit(Format::mhz($usate->usedMhz))), Html::tag('span', $this->translate('Total') . ': ' . Format::mhz($usate->totalMhz)), (new CpuUsage($usate->usedMhz, $usate->totalMhz))->showLabels(false), - $this->translate('CPU'), + $this->translate('CPU') ]), Html::tag('div', $attrBox, [ Html::tag('div', $attr, $this->smallUnit(Format::mBytes($usate->usedMb))), Html::tag('span', $this->translate('Total') . ': ' . Format::mBytes($usate->totalMb)), (new MemoryUsage($usate->usedMb, $usate->totalMb))->showLabels(false), - $this->translate('Memory'), + $this->translate('Memory') ]), Html::tag('div', $attrBox, [ Html::tag('div', $attr, $this->smallUnit( @@ -43,24 +41,20 @@ public function __construct(ResourceUsage $usate) 'span', $this->translate('Total') . ': ' . Format::mBytes($usate->dsCapacity / $mb) ), - (new MemoryUsage( - ($usate->dsCapacity - $usate->dsFreeSpace) / $mb, - $usate->dsCapacity / $mb - ))->showLabels(false), + (new MemoryUsage(($usate->dsCapacity - $usate->dsFreeSpace) / $mb, $usate->dsCapacity / $mb)) + ->showLabels(false), $this->translate('Storage') - ]), + ]) ]); } - protected function smallUnit($string) + protected function smallUnit(string $string): array { $parts = explode(' ', $string, 2); - if (count($parts) < 2) { - return [$parts[0], null]; - } + return [ $parts[0], - Html::tag('span', ['class' => 'unit'], $parts[1]) + count($parts) < 2 ? null : Html::tag('span', ['class' => 'unit'], $parts[1]) ]; } } diff --git a/library/Vspheredb/Web/Widget/VCenterConnectionStatusIcon.php b/library/Vspheredb/Web/Widget/VCenterConnectionStatusIcon.php index d0a14ed3..55f8dca0 100644 --- a/library/Vspheredb/Web/Widget/VCenterConnectionStatusIcon.php +++ b/library/Vspheredb/Web/Widget/VCenterConnectionStatusIcon.php @@ -11,26 +11,18 @@ class VCenterConnectionStatusIcon { public static function create(ServerConnectionInfo $info): Icon { - $state = $info->getState(); - $title = ConnectionState::describe($info); - switch ($state) { - case 'unknown': - return Icon::create('help', ['class' => 'unknown', 'title' => $title]); - case 'disabled': - return Icon::create('cancel', ['title' => $title]); - case ApiConnection::STATE_CONNECTED: - return Icon::create('ok', ['class' => 'green', 'title' => $title]); - case ApiConnection::STATE_LOGIN: - case ApiConnection::STATE_INIT: - return Icon::create('spinner', ['class' => 'yellow', 'title' => $title]); - case ApiConnection::STATE_FAILING: - return Icon::create('warning-empty', ['class' => 'red', 'title' => $title]); - case ApiConnection::STATE_STOPPING: - return Icon::create('cancel', ['class' => 'yellow', 'title' => $title]); - } + $title = ['title' => ConnectionState::describe($info)]; - // Fail, error? - return Icon::create('warning-empty', ['class' => 'warning', 'title' => $title]); + return match ($info->getState()) { + 'unknown' => Icon::create('help', ['class' => 'unknown'] + $title), + 'disabled' => Icon::create('cancel', $title), + ApiConnection::STATE_CONNECTED => Icon::create('ok', ['class' => 'green'] + $title), + ApiConnection::STATE_LOGIN, + ApiConnection::STATE_INIT => Icon::create('spinner', ['class' => 'yellow'] + $title), + ApiConnection::STATE_FAILING => Icon::create('warning-empty', ['class' => 'red'] + $title), + ApiConnection::STATE_STOPPING => Icon::create('cancel', ['class' => 'yellow'] + $title), + default => Icon::create('warning-empty', ['class' => 'warning'] + $title) + }; } public static function noServer(): Icon diff --git a/library/Vspheredb/Web/Widget/VCenterHeader.php b/library/Vspheredb/Web/Widget/VCenterHeader.php index ff349e3f..d6701737 100644 --- a/library/Vspheredb/Web/Widget/VCenterHeader.php +++ b/library/Vspheredb/Web/Widget/VCenterHeader.php @@ -8,24 +8,20 @@ class VCenterHeader extends HtmlDocument { - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VCenter $vCenter) { $this->vCenter = $vCenter; } - protected function assemble() + protected function assemble(): void { - $vCenter = $this->vCenter; - $title = Html::tag('h1', [ - $vCenter->get('name'), - ' ', - Html::tag('small', '(' . $vCenter->getFullName() . ')'), - ]); $this->add([ - $title, + Html::tag( + 'h1', + [$this->vCenter->get('name'), ' ', Html::tag('small', '(' . $this->vCenter->getFullName() . ')')] + ) ]); } } diff --git a/library/Vspheredb/Web/Widget/VCenterSummaries.php b/library/Vspheredb/Web/Widget/VCenterSummaries.php index 9d7b9415..b78fa1fc 100644 --- a/library/Vspheredb/Web/Widget/VCenterSummaries.php +++ b/library/Vspheredb/Web/Widget/VCenterSummaries.php @@ -8,6 +8,7 @@ use Icinga\Module\Vspheredb\Util; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use Zend_Db_Select; class VCenterSummaries extends BaseHtmlElement { @@ -18,43 +19,34 @@ class VCenterSummaries extends BaseHtmlElement 'data-base-target' => '_next' ]; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VCenter $vCenter) { $this->vCenter = $vCenter; } - protected function selectObject($type, $columns) + protected function selectObject(array|string $type, array $columns): Zend_Db_Select { $connection = $this->vCenter->getConnection(); - $db = $connection->getDbAdapter(); - $vCenterUuid = $this->vCenter->getUuid(); - - $query = $db->select()->from(['o' => 'object'], $columns); - if (is_array($type)) { - $query->where('object_type IN (?)', $type); - } else { - $query->where('object_type = ?', $type); - } - $query->where('vcenter_uuid = ?', $connection->quoteBinary($vCenterUuid)); - return $query; + return $connection->getDbAdapter()->select() + ->from(['o' => 'object'], $columns) + ->where('object_type ' . (is_array($type) ? 'IN (?)' : '= ?'), $type) + ->where('vcenter_uuid = ?', $connection->quoteBinary($this->vCenter->getUuid())); } - protected function assemble() + protected function assemble(): void { $connection = $this->vCenter->getConnection(); $db = $connection->getDbAdapter(); - $vCenterUuid = $this->vCenter->getUuid(); $columns = [ 'total' => 'COUNT(*)', 'red' => "SUM(CASE WHEN o.overall_status = 'red' THEN 1 ELSE 0 END)", 'yellow' => "SUM(CASE WHEN o.overall_status = 'yellow' THEN 1 ELSE 0 END)", 'green' => "SUM(CASE WHEN o.overall_status = 'green' THEN 1 ELSE 0 END)", - 'gray' => "SUM(CASE WHEN o.overall_status = 'gray' THEN 1 ELSE 0 END)", + 'gray' => "SUM(CASE WHEN o.overall_status = 'gray' THEN 1 ELSE 0 END)" ]; $this->addCountlet( @@ -80,10 +72,11 @@ protected function assemble() ); $this->addCountlet( $db->fetchRow( - $db->select()->from(['o' => 'object'], $columns) + $db->select() + ->from(['o' => 'object'], $columns) ->join(['vm' => 'virtual_machine'], 'vm.uuid = o.uuid', []) ->where('vm.template = ?', 'n') - ->where('vm.vcenter_uuid = ?', $connection->quoteBinary($vCenterUuid)) + ->where('vm.vcenter_uuid = ?', $connection->quoteBinary($this->vCenter->getUuid())) ), 'Virtual Machines', 'vspheredb/vms' @@ -143,7 +136,7 @@ protected function assemble() ); } - protected function getWorstState($counters) + protected function getWorstState(object $counters): string { foreach (['red', 'yellow', 'gray', 'green'] as $color) { if ($counters->$color > 0) { @@ -155,17 +148,14 @@ protected function getWorstState($counters) return 'gray'; } - protected function addCountlet($counters, $title, $url) + protected function addCountlet(object $counters, string $title, string $url): void { if ((int) $counters->total === 0) { return; } $url = Url::fromPath($url)->with('vcenter', Util::niceUuid($this->vCenter->getUuid())); $state = $this->getWorstState($counters); - $title = Html::tag('h3', [ - Link::create($title, $url), - ' (' . $counters->total . ')' - ]); + $title = Html::tag('h3', [Link::create($title, $url), ' (' . $counters->total . ')']); $cell = Html::tag('div', ['class' => ['summary-countlet', "state-$state"]]); $cell->add($title); diff --git a/library/Vspheredb/Web/Widget/VCenterSyncInfo.php b/library/Vspheredb/Web/Widget/VCenterSyncInfo.php index 253df408..8b7d0e15 100644 --- a/library/Vspheredb/Web/Widget/VCenterSyncInfo.php +++ b/library/Vspheredb/Web/Widget/VCenterSyncInfo.php @@ -7,6 +7,7 @@ use Icinga\Module\Vspheredb\WebUtil; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\I18n\Translation; class VCenterSyncInfo extends BaseHtmlElement @@ -17,8 +18,7 @@ class VCenterSyncInfo extends BaseHtmlElement protected $defaultAttributes = ['class' => 'health']; - /** @var VCenter */ - protected $vCenter; + protected VCenter $vCenter; public function __construct(VCenter $vCenter) { @@ -59,19 +59,17 @@ protected function assemble() } } - protected function getVersionInfoString() + protected function getVersionInfoString(): string { - $c = $this->vCenter; - return sprintf( '%s %s build-%s', - $c->get('api_type'), - $c->get('version'), - $c->get('build') + $this->vCenter->get('api_type'), + $this->vCenter->get('version'), + $this->vCenter->get('build') ); } - protected function healthDiv($state, $content = null) + protected function healthDiv(string $state, $content = null): HtmlElement { return Html::tag('div', ['class' => ['health', $state]], $content); } diff --git a/library/Vspheredb/Web/Widget/VMotionHeatmap.php b/library/Vspheredb/Web/Widget/VMotionHeatmap.php index 027b98a9..8c344919 100644 --- a/library/Vspheredb/Web/Widget/VMotionHeatmap.php +++ b/library/Vspheredb/Web/Widget/VMotionHeatmap.php @@ -3,16 +3,16 @@ namespace Icinga\Module\Vspheredb\Web\Widget; use Icinga\Module\Vspheredb\Db; +use Zend_Db_Adapter_Abstract; use Zend_Db_Select as ZfSelect; class VMotionHeatmap { - /** @var \Zend_Db_Adapter_Abstract */ - protected $db; + protected Zend_Db_Adapter_Abstract $db; - protected $query; + protected ?ZfSelect $query = null; - protected $eventType; + protected ?string $eventType = null; public function __construct(Db $connection) { @@ -24,19 +24,20 @@ public function getEvents(): array return $this->db->fetchPairs($this->getQuery()); } - public function filterEventType($type): self + public function filterEventType(?string $type): static { $this->eventType = $type; return $this; } - public function filterParent($uuid): self + public function filterParent(string $uuid): static { - $this->getQuery()->join(['h' => 'object'], $this->db->quoteInto( - 'h.uuid = veh.host_uuid AND h.parent_uuid = ?', - $uuid - ), []); + $this->getQuery()->join( + ['h' => 'object'], + $this->db->quoteInto('h.uuid = veh.host_uuid AND h.parent_uuid = ?', $uuid), + [] + ); return $this; } @@ -44,17 +45,17 @@ public function filterParent($uuid): self protected function prepareQuery(): ZfSelect { $maxDays = 400; - $query = $this->db->select()->from(['veh' => 'vm_event_history'], [ - // TODO: / 86400 + offset - 'day' => 'DATE(FROM_UNIXTIME(veh.ts_event_ms / 1000))', - 'cnt' => 'COUNT(*)' - ])->where('veh.ts_event_ms > ?', time() * 1000 - 86400 * $maxDays * 1000)->group('day'); + $query = $this->db->select() + ->from(['veh' => 'vm_event_history'], [ + // TODO: / 86400 + offset + 'day' => 'DATE(FROM_UNIXTIME(veh.ts_event_ms / 1000))', + 'cnt' => 'COUNT(*)' + ]) + ->where('veh.ts_event_ms > ?', time() * 1000 - 86400 * $maxDays * 1000) + ->group('day'); if ($this->eventType !== null && $this->eventType !== '') { - $query->where( - 'veh.event_type = ?', - $this->eventType - ); + $query->where('veh.event_type = ?', $this->eventType); } return $query; @@ -62,10 +63,6 @@ protected function prepareQuery(): ZfSelect protected function getQuery(): ZfSelect { - if ($this->query === null) { - $this->query = $this->prepareQuery(); - } - - return $this->query; + return $this->query ??= $this->prepareQuery(); } } diff --git a/library/Vspheredb/Web/Widget/Vm/BackupToolInfo.php b/library/Vspheredb/Web/Widget/Vm/BackupToolInfo.php index 52f80bdb..00a379db 100644 --- a/library/Vspheredb/Web/Widget/Vm/BackupToolInfo.php +++ b/library/Vspheredb/Web/Widget/Vm/BackupToolInfo.php @@ -17,15 +17,14 @@ class BackupToolInfo extends HtmlDocument { use Translation; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; public function __construct(VirtualMachine $vm) { $this->vm = $vm; } - protected function assemble() + protected function assemble(): void { $vm = $this->vm; $this->add(new SubTitle($this->translate('Backup-Tools'), 'download')); @@ -40,25 +39,22 @@ protected function assemble() } } if ($seenBackupTools === 0) { - $this->add(Html::tag( - 'p', - null, - $this->translate('No known backup tool has been used for this VM') - )); + $this->add(Html::tag('p', null, $this->translate('No known backup tool has been used for this VM'))); } } /** * TODO: Use a hook once the API stabilized + * * @return BackupTool[] */ - protected function getBackupTools() + protected function getBackupTools(): array { return [ new IbmSpectrumProtect(), new NetBackup(), new VeeamBackup(), - new VRangerBackup(), + new VRangerBackup() ]; } } diff --git a/library/Vspheredb/Web/Widget/VmHardwareTree.php b/library/Vspheredb/Web/Widget/VmHardwareTree.php index 144fcf41..7abbdb5c 100644 --- a/library/Vspheredb/Web/Widget/VmHardwareTree.php +++ b/library/Vspheredb/Web/Widget/VmHardwareTree.php @@ -3,15 +3,15 @@ namespace Icinga\Module\Vspheredb\Web\Widget; use gipfl\IcingaWeb2\Link; -use Icinga\Module\Vspheredb\Db; +use Icinga\Module\Vspheredb\Db\DbConnection; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\PathLookup; use Icinga\Module\Vspheredb\Util; use Icinga\Util\Format; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use ipl\Html\HtmlElement; use ipl\I18n\Translation; -use Ramsey\Uuid\Uuid; class VmHardwareTree extends BaseHtmlElement { @@ -21,25 +21,24 @@ class VmHardwareTree extends BaseHtmlElement protected $defaultAttributes = [ 'class' => 'tree', - 'data-base-target' => '_next', + 'data-base-target' => '_next' ]; protected $tree; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - protected $devices = []; + protected array $devices = []; - protected $parents = []; + protected array $parents = []; - protected $children = []; + protected array $children = []; - protected $disks = []; + protected array $disks = []; - protected $nics = []; + protected array $nics = []; - protected $diskPerf; + protected ?array $diskPerf = null; public function __construct(VirtualMachine $vm) { @@ -47,14 +46,14 @@ public function __construct(VirtualMachine $vm) } /** - * @return Db + * @return DbConnection */ - protected function getDb() + protected function getDb(): DbConnection { return $this->vm->getConnection(); } - protected function fetchDisks() + protected function fetchDisks(): void { $connection = $this->getDb(); $db = $connection->getDbAdapter(); @@ -69,7 +68,7 @@ protected function fetchDisks() } } - protected function fetchNics() + protected function fetchNics(): void { $connection = $this->getDb(); $db = $connection->getDbAdapter(); @@ -84,7 +83,7 @@ protected function fetchNics() } } - protected function fetchHardware() + protected function fetchHardware(): void { $this->fetchDisks(); $this->fetchNics(); @@ -107,7 +106,7 @@ protected function fetchHardware() } } - protected function renderDisk($disk, $device, $controller) + protected function renderDisk(object $disk, object $device, object $controller): array { $lookup = new PathLookup($this->getDb()->getDbAdapter()); $result = []; @@ -139,57 +138,40 @@ protected function renderDisk($disk, $device, $controller) $result[] = Format::bytes($disk->capacity); } - if (false && array_key_exists($scsi, $this->diskPerf)) { - $result[] = new CompactInOutSparkline( - $this->diskPerf[$scsi][171], - $this->diskPerf[$scsi][172] - ); - } - return $result; } - protected function renderNic($nic, $device, $controller) + protected function renderNic(object $nic, object $device, object $controller): Link|array { - $desc = $device->label; - $parts[] = $nic->mac_address; if ($device->summary !== $device->label) { - // $parts[] = $device->summary; + $parts[] = $device->summary; } - $desc = $desc . ': ' . implode(', ', $parts); - - $result = Link::create($desc, '#', null, [ - 'class' => 'icon-sitemap', - ]); + $result = Link::create( + $device->label . ': ' . implode(', ', $parts), + '#', + null, + ['class' => 'icon-sitemap'] + ); - if ($nic->portgroup_uuid === null) { - return $result; - } else { - return [$result, $this->linkToPortGroup($nic->portgroup_uuid)]; - } + return $nic->portgroup_uuid === null ? $result : [$result, $this->linkToPortGroup($nic->portgroup_uuid)]; } - protected function linkToPortGroup($uuid) + protected function linkToPortGroup($uuid): string { $connection = $this->getDb(); $db = $connection->getDbAdapter(); $info = $db->fetchRow( - $db->select()->from( - ['o' => 'object'], - [ + $db->select() + ->from(['o' => 'object'], [ 'uuid' => 'o.uuid', 'object_name' => 'o.object_name', - 'cnt_nics' => 'COUNT(*)', - ] - )->join( - ['vna' => 'vm_network_adapter'], - 'vna.portgroup_uuid = o.uuid', - [] - ) - ->where('o.uuid = ?', $connection->quoteBinary($uuid)) - ->group('o.uuid') + 'cnt_nics' => 'COUNT(*)' + ]) + ->join(['vna' => 'vm_network_adapter'], 'vna.portgroup_uuid = o.uuid', []) + ->where('o.uuid = ?', $connection->quoteBinary($uuid)) + ->group('o.uuid') ); if (false === $info) { @@ -197,16 +179,9 @@ protected function linkToPortGroup($uuid) } return sprintf('%s (%d NICs)', $info->object_name, $info->cnt_nics); - - // TODO: - return Link::create( - sprintf('%s (%d NICs)', $info->object_name, $info->cnt_nics), - 'vspheredb/portgroup', - Util::uuidParams($info->uuid) - ); } - protected function fetchDiskPerf() + protected function fetchDiskPerf(): array { $connection = $this->getDb(); $db = $connection->getDbAdapter(); @@ -216,16 +191,18 @@ protected function fetchDiskPerf() "COALESCE(value_minus3, '0')", "COALESCE(value_minus2, '0')", "COALESCE(value_minus1, '0')", - 'value_last', + 'value_last' ]) . ')'; - $query = $db->select()->from('counter_300x5', [ - // 'name' => 'object_uuid', - 'instance', - 'counter_key', - 'value' => $values, - ])->where('object_uuid = ?', $connection->quoteBinary($this->vm->get('uuid'))) - ->where('counter_key IN (?)', [171, 172]); + $query = $db->select() + ->from('counter_300x5', [ + // 'name' => 'object_uuid', + 'instance', + 'counter_key', + 'value' => $values + ]) + ->where('object_uuid = ?', $connection->quoteBinary($this->vm->get('uuid'))) + ->where('counter_key IN (?)', [171, 172]); $rows = $db->fetchAll($query); $result = []; @@ -238,13 +215,13 @@ protected function fetchDiskPerf() } - public function assemble() + protected function assemble(): void { $this->fetchHardware(); $this->add($this->renderNodes($this->parents)); } - protected function renderNodes($nodes, $level = 0) + protected function renderNodes(array $nodes, int $level = 0): HtmlElement|array { $result = []; foreach ($nodes as $child) { @@ -253,12 +230,12 @@ protected function renderNodes($nodes, $level = 0) if ($level === 0) { return $result; - } else { - return Html::tag('ul', null, $result); } + + return Html::tag('ul', null, $result); } - protected function renderNode($device, $level = 0) + protected function renderNode(object $device, int $level = 0): HtmlElement { /** @var int $key */ $key = $device->hardware_key; @@ -271,7 +248,7 @@ protected function renderNode($device, $level = 0) // TODO: get serious: // $isNic = array_key_exists($key, $this->nics - $isNic = strpos($desc, 'Network') === 0; + $isNic = str_starts_with($desc, 'Network'); if ($isDisk) { $class = 'icon-database'; @@ -282,12 +259,11 @@ protected function renderNode($device, $level = 0) } $li = Html::tag('li'); - if (! $hasChildren) { - $li->getAttributes()->add('class', 'collapsed'); - } if ($hasChildren) { $li->add(Html::tag('span', ['class' => 'handle'])); + } else { + $li->getAttributes()->add('class', 'collapsed'); } /** @var int|string $controllerKey */ @@ -295,11 +271,11 @@ protected function renderNode($device, $level = 0) if ($isDisk) { $li->add($this->renderDisk($this->disks[$key], $device, $this->devices[$controllerKey])); } elseif ($isNic) { - if (array_key_exists($key, $this->nics)) { - $li->add($this->renderNic($this->nics[$key], $device, $this->devices[$controllerKey])); - } else { - $li->add(Link::create($desc, '#', null, ['class' => $class, 'title' => 'No more details available'])); - } + $li->add( + array_key_exists($key, $this->nics) + ? $this->renderNic($this->nics[$key], $device, $this->devices[$controllerKey]) + : Link::create($desc, '#', null, ['class' => $class, 'title' => 'No more details available']) + ); } else { $li->add(Link::create($desc, '#', null, ['class' => $class])); } diff --git a/library/Vspheredb/Web/Widget/VmHeader.php b/library/Vspheredb/Web/Widget/VmHeader.php index f5609dc4..e2006ca8 100644 --- a/library/Vspheredb/Web/Widget/VmHeader.php +++ b/library/Vspheredb/Web/Widget/VmHeader.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Vspheredb\Web\Widget; use gipfl\IcingaWeb2\Icon; +use Icinga\Exception\NotFoundError; use Icinga\Module\Vspheredb\Data\Anonymizer; use Icinga\Module\Vspheredb\DbObject\VirtualMachine; use Icinga\Module\Vspheredb\DbObject\VmQuickStats; @@ -14,17 +15,13 @@ class VmHeader extends BaseHtmlElement { use Translation; - /** @var VirtualMachine */ - protected $vm; + protected VirtualMachine $vm; - /** @var VmQuickStats */ - protected $quickStats; + protected VmQuickStats $quickStats; protected $tag = 'div'; - protected $defaultAttributes = [ - 'class' => 'vm-header' - ]; + protected $defaultAttributes = ['class' => 'vm-header']; public function __construct(VirtualMachine $vm, VmQuickStats $quickStats) { @@ -33,9 +30,9 @@ public function __construct(VirtualMachine $vm, VmQuickStats $quickStats) } /** - * @throws \Icinga\Exception\NotFoundError + * @throws NotFoundError */ - protected function assemble() + protected function assemble(): void { $vm = $this->vm; $vm->object()->set('object_name', Anonymizer::anonymizeString($vm->object()->get('object_name'))); @@ -45,25 +42,17 @@ protected function assemble() $powerState = $vm->get('runtime_power_state'); $renderer = new PowerStateRenderer(); if ($vm->get('template') === 'y') { - $cpu = Html::tag('div', [ - 'class' => 'vm-template' - ], Icon::create('upload', [ + $cpu = Html::tag('div', ['class' => 'vm-template'], Icon::create('upload', [ 'title' => $this->translate('This is a template'), - 'class' => [ 'state' ] + 'class' => ['state'] ])); $mem = $this->translate('This is a template'); } elseif ($powerState !== 'poweredOn') { - $cpu = Html::tag('div', [ - 'class' => 'cpu off', - // 'style' => 'font-size: 3em; width: 1em; height: 1em; display: inline-block;', - ], $renderer($powerState)); + $cpu = Html::tag('div', ['class' => 'cpu off'], $renderer($powerState)); $mem = $renderer->getPowerStateDescription($powerState); } else { - $cpu = new CpuAbsoluteUsage( - $this->quickStats->get('overall_cpu_usage'), - $vm->get('hardware_numcpu') - ); + $cpu = new CpuAbsoluteUsage($this->quickStats->get('overall_cpu_usage'), $vm->get('hardware_numcpu')); $mem = new MemoryUsage( $this->quickStats->get('guest_memory_usage_mb'), $vm->get('hardware_memorymb'), @@ -71,10 +60,6 @@ protected function assemble() ); } $title = Html::tag('h1', $vm->object()->get('object_name')); - $this->add([ - $cpu, - $title, - $mem - ]); + $this->add([$cpu, $title, $mem]); } } diff --git a/library/Vspheredb/Web/Widget/VmRouteConfigTable.php b/library/Vspheredb/Web/Widget/VmRouteConfigTable.php index f85daa9d..6b081c5a 100644 --- a/library/Vspheredb/Web/Widget/VmRouteConfigTable.php +++ b/library/Vspheredb/Web/Widget/VmRouteConfigTable.php @@ -11,15 +11,14 @@ class VmRouteConfigTable extends HtmlDocument { use Translation; - /** @var VirtualMachine */ - protected $object; + protected VirtualMachine $object; public function __construct(VirtualMachine $object) { $this->object = $object; } - protected function assemble() + protected function assemble(): void { $object = $this->object; $this->prepend(new SubTitle($this->translate('Guest Routing Table'), 'sitemap')); @@ -29,10 +28,11 @@ protected function assemble() } else { $table = new Table(); foreach ($stacks as $stack) { - $table->add(Table::row([ - $this->translate('Network'), - $this->translate('Gateway') - ], ['class' => 'text-left'], 'th')); + $table->add(Table::row( + [$this->translate('Network'), $this->translate('Gateway')], + ['class' => 'text-left'], + 'th' + )); if (! isset($stack->ipRouteConfig->ipRoute)) { continue; } @@ -48,10 +48,7 @@ protected function assemble() if (empty($gateway)) { $gateway[] = '-'; } - $table->add(Table::row([ - $route->network . '/' . $route->prefixLength, - implode(', ', $gateway), - ])); + $table->add(Table::row([$route->network . '/' . $route->prefixLength, implode(', ', $gateway)])); } } $this->add($table); diff --git a/library/Vspheredb/WebUtil.php b/library/Vspheredb/WebUtil.php index db2e8360..374ff2f2 100644 --- a/library/Vspheredb/WebUtil.php +++ b/library/Vspheredb/WebUtil.php @@ -6,23 +6,21 @@ use ipl\Html\Error as HtmlError; use ipl\Html\Html; use ipl\Html\HtmlDocument; +use ipl\Html\HtmlElement; use Throwable; -use Exception; class WebUtil { - public static function runFailSafe($callback, HtmlDocument $parent) + public static function runFailSafe(callable $callback, HtmlDocument $parent): void { try { $callback(); - } catch (Exception $e) { - $parent->add(HtmlError::show($e)); } catch (Throwable $e) { $parent->add(HtmlError::show($e)); } } - public static function timeAgo($time) + public static function timeAgo(float|int $time): HtmlElement { return Html::tag('span', [ 'class' => 'time-ago', diff --git a/run-missingdeps.php b/run-missingdeps.php deleted file mode 100644 index e110feea..00000000 --- a/run-missingdeps.php +++ /dev/null @@ -1,23 +0,0 @@ -isCli()) { - throw new IcingaException( - "Missing dependencies, please check " - ); -} else { - $request = Icinga::app()->getRequest(); - $path = $request->getPathInfo(); - if (! preg_match('#^/vspheredb#', $path)) { - return; - } - if (preg_match('#^/vspheredb/phperror/dependencies#', $path)) { - return; - } - - header('Location: ' . Url::fromPath('vspheredb/phperror/dependencies')); - exit; -} diff --git a/run.php b/run.php index 0f19e5f7..39b1e30a 100644 --- a/run.php +++ b/run.php @@ -1,17 +1,9 @@ app); -if (! $checker->satisfiesDependencies($this)) { - include __DIR__ . '/run-missingdeps.php'; - return; -} - $this->provideHook('director/ImportSource'); $this->provideHook('director/DataType', DataTypeMonitoringRule::class); $this->provideHook('vspheredb/PerfDataConsumer', PerfDataConsumerInfluxDb::class);