From 92b7a845a0542cdc90d9524097f71c7e9175258a Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Sat, 9 Nov 2019 21:33:32 +0100 Subject: [PATCH] Actually integrate into the monitoring module --- application/forms/Monitoring/PackagesForm.php | 205 ++++++++++++++++++ application/forms/PackagesFormTrait.php | 58 +++++ application/forms/Pending/PackagesForm.php | 60 +---- .../Monitoring/DetailviewExtension.php | 34 +++ .../Web/InvertableCheckboxesTrait.php | 11 + public/css/module.less | 17 +- public/js/module.js | 16 -- run.php | 5 + 8 files changed, 330 insertions(+), 76 deletions(-) create mode 100644 application/forms/Monitoring/PackagesForm.php create mode 100644 application/forms/PackagesFormTrait.php create mode 100644 library/Masifupgrader/ProvidedHook/Monitoring/DetailviewExtension.php create mode 100644 library/Masifupgrader/Web/InvertableCheckboxesTrait.php create mode 100644 run.php diff --git a/application/forms/Monitoring/PackagesForm.php b/application/forms/Monitoring/PackagesForm.php new file mode 100644 index 0000000..87e606d --- /dev/null +++ b/application/forms/Monitoring/PackagesForm.php @@ -0,0 +1,205 @@ +tasks === null) { + $rawTasks = $this->fetchAll( + <<agent] + ); + + $this->tasks = []; + + foreach ($rawTasks as list($package, $action, $toVersion)) { + $this->tasks[$package][$action][$toVersion] = null; + } + } + + return $this->tasks; + } + + public function init() + { + $this->setName('form_monitoring_packages'); + $this->setSubmitLabel($this->translate('Approve selection')); + } + + public function createElements(array $formData) + { + foreach ($this->getTasks() as $package => $actions) { + foreach ($actions as $action => $toVersions) { + foreach ($toVersions as $toVersion => $_) { + $checkboxName = implode('_', [bin2hex($package), $action, bin2hex($toVersion)]); + $this->addElement('checkbox', $checkboxName, []); + } + } + } + } + + public function render(Zend_View_Interface $view = null) + { + $this->create(); + + foreach ($this->getElements() as $element) { + if ($element instanceof Zend_Form_Element_Checkbox || $element instanceof Zend_Form_Element_Submit) { + $element->setDecorators([ + 'Zend_Form_Decorator_ViewHelper' => $element->getDecorators()['Zend_Form_Decorator_ViewHelper'] + ]); + } + } + + if ($view === null) { + $view = $this->getView(); + } + + $t1header1 = $this->translate('Package'); + $t1header2 = $this->translate('Action'); + $t1header3 = $this->translate('Target version'); + $invertTrigger = $this->translate('(invert selection)'); + + $result = "
" + . $this->getElement($this->getUidElementName())->render($view) + . $this->getElement($this->getTokenElementName())->render($view) + . "" + . "" + . ""; + + $rows = []; + $currentRow = 0; + + $actionLabels = [ + 'install' => $this->translate('Install'), + 'update' => $this->translate('Update'), + 'configure' => $this->translate('Configure'), + 'remove' => $this->translate('Remove'), + 'purge' => $this->translate('Purge') + ]; + + $actionsOrder = array_flip(array_keys($actionLabels)); + + foreach ($this->getTasks() as $package => $actions) { + $packageRows = 0; + $packageOnRow = $currentRow; + + uksort($actions, function($lhs, $rhs) use($actionsOrder) { + return $actionsOrder[$lhs] - $actionsOrder[$rhs]; + }); + + foreach ($actions as $action => $toVersions) { + $actionOnRow = $currentRow; + + krsort($toVersions, SORT_NATURAL); + + foreach ($toVersions as $toVersion => $_) { + if ($toVersion === '') { + $toVersion = $this->translate('N/A'); + } + + $approve = $this->getElement(implode('_', [bin2hex($package), $action, bin2hex($toVersion)])); + + $rows[] = [ + null, + null, + "" + ]; + + ++$currentRow; + } + + $actionRows = count($toVersions); + $packageRows += $actionRows; + $rows[$actionOnRow][1] = ""; + } + + $rows[$packageOnRow][0] = ""; + } + + foreach ($rows as $row) { + $result .= '' . implode('', $row) . ''; + } + + return "$result
{$view->escape($t1header1)}{$view->escape($t1header2)}{$view->escape($t1header3)} {$view->escape($invertTrigger)}
{$approve->render($view)}{$view->escape($actionLabels[$action])}{$view->escape($package)}
{$this->getElement('btn_submit')->render($view)}
"; + } + + public function onSuccess() + { + $taskFilter = []; + + foreach ($this->getTasks() as $package => $actions) { + foreach ($actions as $action => $toVersions) { + foreach ($toVersions as $toVersion => $_) { + /** @var Zend_Form_Element_Checkbox $checkbox */ + $checkbox = $this->getElement(implode('_', [bin2hex($package), $action, bin2hex($toVersion)])); + + if ($checkbox->isChecked()) { + $taskFilter[$package][$action][$toVersion] = null; + } + } + } + } + + if (empty($taskFilter)) { + return false; + } + + list($packageFilters, $packageFilterParams) = $this->filterTasksByActions('t', 'p2', $taskFilter); + + $filter = "t.approved=0 AND t.agent=(SELECT a.id FROM agent a WHERE a.name=?) AND ($packageFilters)"; + $params = array_merge([$this->agent], $packageFilterParams); + + $this->transaction(function() use($filter, $params) { + $this->execSql("UPDATE task t SET t.approved=1 WHERE $filter", $params); + }); + + return true; + } + + /** + * @param string $agent + * + * @return PackagesForm + */ + public function setAgent($agent) + { + $this->agent = $agent; + return $this; + } +} diff --git a/application/forms/PackagesFormTrait.php b/application/forms/PackagesFormTrait.php new file mode 100644 index 0000000..048caaf --- /dev/null +++ b/application/forms/PackagesFormTrait.php @@ -0,0 +1,58 @@ + $actions) { + $params[] = $package; + $actionFilters = []; + + foreach ($actions as $action => $toVersions) { + $params[] = $action; + + $toVersionHasNull = false; + $toVersionsNotNull = 0; + + foreach ($toVersions as $toVersion => $_) { + if ($toVersion === '') { + $toVersionHasNull = true; + } else { + ++$toVersionsNotNull; + $params[] = $toVersion; + } + } + + $toVersionFilters = []; + + if ($toVersionHasNull) { + $toVersionFilters[] = "$t.to_version IS NULL"; + } + + if ($toVersionsNotNull) { + $toVersionFilters[] = "$t.to_version IN (" . implode(',', array_fill(0, $toVersionsNotNull, '?')) . ')'; + } + + $actionFilters[] = "($t.action=? AND (" . implode(' OR ', $toVersionFilters) . '))'; + } + + $packageFilters[] = "($t.package=(SELECT $p.id FROM package $p WHERE $p.name=?) AND (" . implode(' OR ', $actionFilters) . '))'; + } + + return [implode(' OR ', $packageFilters), $params]; + } +} diff --git a/application/forms/Pending/PackagesForm.php b/application/forms/Pending/PackagesForm.php index 78184e1..048aa45 100644 --- a/application/forms/Pending/PackagesForm.php +++ b/application/forms/Pending/PackagesForm.php @@ -2,7 +2,9 @@ namespace Icinga\Module\Masifupgrader\Forms\Pending; +use Icinga\Module\Masifupgrader\Forms\PackagesFormTrait; use Icinga\Module\Masifupgrader\Web\DbAwareFormTrait; +use Icinga\Module\Masifupgrader\Web\InvertableCheckboxesTrait; use Icinga\Web\Form; use Zend_Form_Element_Checkbox; use Zend_Form_Element_Submit; @@ -11,6 +13,8 @@ class PackagesForm extends Form { use DbAwareFormTrait; + use InvertableCheckboxesTrait; + use PackagesFormTrait; /** * @var array @@ -91,58 +95,6 @@ protected function getAgents($filter = []) return $this->agents; } - /** - * @param string $tasksTableAlias - * @param string $packagesTableAlias - * @param string $filter - * - * @return array - */ - protected function filterTasksByActions($tasksTableAlias, $packagesTableAlias, $filter) - { - $t = $tasksTableAlias; - $p = $packagesTableAlias; - $params = []; - $packageFilters = []; - - foreach ($filter as $package => $actions) { - $params[] = $package; - $actionFilters = []; - - foreach ($actions as $action => $toVersions) { - $params[] = $action; - - $toVersionHasNull = false; - $toVersionsNotNull = 0; - - foreach ($toVersions as $toVersion => $_) { - if ($toVersion === '') { - $toVersionHasNull = true; - } else { - ++$toVersionsNotNull; - $params[] = $toVersion; - } - } - - $toVersionFilters = []; - - if ($toVersionHasNull) { - $toVersionFilters[] = "$t.to_version IS NULL"; - } - - if ($toVersionsNotNull) { - $toVersionFilters[] = "$t.to_version IN (" . implode(',', array_fill(0, $toVersionsNotNull, '?')) . ')'; - } - - $actionFilters[] = "($t.action=? AND (" . implode(' OR ', $toVersionFilters) . '))'; - } - - $packageFilters[] = "($t.package=(SELECT $p.id FROM package $p WHERE $p.name=?) AND (" . implode(' OR ', $actionFilters) . '))'; - } - - return [implode(' OR ', $packageFilters), $params]; - } - public function init() { $this->setName('form_pending_packages'); @@ -212,7 +164,9 @@ public function render(Zend_View_Interface $view = null) . $filterAgents . "" . "" - . ""; + . ""; $rows = []; $currentRow = 0; diff --git a/library/Masifupgrader/ProvidedHook/Monitoring/DetailviewExtension.php b/library/Masifupgrader/ProvidedHook/Monitoring/DetailviewExtension.php new file mode 100644 index 0000000..e61689f --- /dev/null +++ b/library/Masifupgrader/ProvidedHook/Monitoring/DetailviewExtension.php @@ -0,0 +1,34 @@ +get('integration', 'monitoring', '0') + && Config::module('masifupgrader')->get('services', $object->getName(), '0') + ) { + $this->init(); + + $view = $this->getView(); + + $form = new PackagesForm(); + $form->setDb($this->db)->setAgent($object->getHost()->getName())->handleRequest(); + + return '

' . $view->escape(mt('masifupgrader', 'Masif Upgrader')) . '

' . $form->render($view); + } + + return ''; + } +} diff --git a/library/Masifupgrader/Web/InvertableCheckboxesTrait.php b/library/Masifupgrader/Web/InvertableCheckboxesTrait.php new file mode 100644 index 0000000..f11d741 --- /dev/null +++ b/library/Masifupgrader/Web/InvertableCheckboxesTrait.php @@ -0,0 +1,11 @@ +provideHook('monitoring/DetailviewExtension');
{$view->escape($t1header1)}{$view->escape($t1header2)}{$view->escape($t1header3)} {$view->escape($invertTrigger)}
{$view->escape($t1header3)} {$view->escape($invertTrigger)}