From 6b4a3cbc0cb088cee2632c505966deee140c99ed Mon Sep 17 00:00:00 2001 From: Sukhwinder Dhillon Date: Fri, 9 Jun 2023 10:33:22 +0200 Subject: [PATCH 1/5] Do not break overview page if existing `business-process` has invalid config - Add icon and config file name to broken `business-process` - Use font-awesome icon --- .../Web/Component/BpDashboardTile.php | 10 ++++------ .../Businessprocess/Web/Component/Dashboard.php | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/library/Businessprocess/Web/Component/BpDashboardTile.php b/library/Businessprocess/Web/Component/BpDashboardTile.php index 17d3a0c..9a4a0f6 100644 --- a/library/Businessprocess/Web/Component/BpDashboardTile.php +++ b/library/Businessprocess/Web/Component/BpDashboardTile.php @@ -3,10 +3,12 @@ namespace Icinga\Module\Businessprocess\Web\Component; use Icinga\Module\Businessprocess\BpConfig; -use Icinga\Web\Url; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; use ipl\Html\Text; +use ipl\Web\Url; +use ipl\Web\Widget\Icon; +use ipl\Web\Widget\Link; class BpDashboardTile extends BaseHtmlElement { @@ -16,14 +18,10 @@ class BpDashboardTile extends BaseHtmlElement public function __construct(BpConfig $bp, $title, $description, $icon, $url, $urlParams = null, $attributes = null) { - if (! isset($attributes['href'])) { - $attributes['href'] = Url::fromPath($url, $urlParams ?: []); - } - $this->add(Html::tag( 'div', ['class' => 'bp-link', 'data-base-target' => '_main'], - Html::tag('a', $attributes, Html::tag('i', ['class' => 'icon icon-' . $icon])) + (new Link(new Icon($icon), Url::fromPath($url, $urlParams ?: []), $attributes)) ->add(Html::tag('span', ['class' => 'header'], $title)) ->add($description) )); diff --git a/library/Businessprocess/Web/Component/Dashboard.php b/library/Businessprocess/Web/Component/Dashboard.php index 3423b2f..e78c46c 100644 --- a/library/Businessprocess/Web/Component/Dashboard.php +++ b/library/Businessprocess/Web/Component/Dashboard.php @@ -2,8 +2,10 @@ namespace Icinga\Module\Businessprocess\Web\Component; +use Exception; use Icinga\Application\Modules\Module; use Icinga\Authentication\Auth; +use Icinga\Module\Businessprocess\BpConfig; use Icinga\Module\Businessprocess\ProvidedHook\Icingadb\IcingadbSupport; use Icinga\Module\Businessprocess\State\IcingaDbState; use Icinga\Module\Businessprocess\State\MonitoringState; @@ -92,7 +94,20 @@ class Dashboard extends BaseHtmlElement $title = $name; } - $bp = $storage->loadProcess($name); + try { + $bp = $storage->loadProcess($name); + } catch (Exception $e) { + $this->add(new BpDashboardTile( + new BpConfig(), + $title, + sprintf(t('File %s has invalid config'), $name . '.conf'), + 'file-circle-xmark', + 'businessprocess/process/show', + ['config' => $name] + )); + + continue; + } if (Module::exists('icingadb') && (! $bp->hasBackendName() && IcingadbSupport::useIcingaDbAsBackend()) From 834005f7b4ccf37ede463e9d4b896f596480c093 Mon Sep 17 00:00:00 2001 From: Sukhwinder Dhillon Date: Mon, 17 Jul 2023 13:38:10 +0200 Subject: [PATCH 2/5] Don't break `impact-action` page if bp has invalid config - Add message for invalid config --- application/controllers/NodeController.php | 38 +++++++++++++++++++++- public/css/module.less | 16 +++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/application/controllers/NodeController.php b/application/controllers/NodeController.php index 8addc07..80e6676 100644 --- a/application/controllers/NodeController.php +++ b/application/controllers/NodeController.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Businessprocess\Controllers; +use Exception; use Icinga\Application\Modules\Module; use Icinga\Module\Businessprocess\ProvidedHook\Icingadb\IcingadbSupport; use Icinga\Module\Businessprocess\Renderer\Breadcrumb; @@ -11,6 +12,8 @@ use Icinga\Module\Businessprocess\State\IcingaDbState; use Icinga\Module\Businessprocess\State\MonitoringState; use Icinga\Module\Businessprocess\Web\Controller; use Icinga\Module\Businessprocess\Web\Url; +use ipl\Html\Html; +use ipl\Web\Widget\Link; class NodeController extends Controller { @@ -24,9 +27,16 @@ class NodeController extends Controller $name = $this->params->get('name'); $this->addTitle($this->translate('Business Impact (%s)'), $name); + $brokenFiles = []; $simulation = Simulation::fromSession($this->session()); foreach ($this->storage()->listProcessNames() as $configName) { - $config = $this->storage()->loadProcess($configName); + try { + $config = $this->storage()->loadProcess($configName); + } catch (Exception $e) { + $meta = $this->storage()->loadMetadata($configName); + $brokenFiles[$meta->get('Title')] = $configName; + continue; + } $parents = []; if ($config->hasNode($name)) { @@ -108,5 +118,31 @@ class NodeController extends Controller if ($content->isEmpty()) { $content->add($this->translate('No impact detected. Is this node part of a business process?')); } + + if (! empty($brokenFiles)) { + $elem = Html::tag( + 'ul', + ['class' => 'broken-files'], + tp( + 'The following business process has an invalid config file and therefore cannot be read:', + 'The following business processes have invalid config files and therefore cannot be read:', + count($brokenFiles) + ) + ); + + foreach ($brokenFiles as $bpName => $fileName) { + $elem->addHtml( + Html::tag( + 'li', + new Link( + sprintf('%s (%s.conf)', $bpName, $fileName), + (string) Url::fromPath('businessprocess/process/show', ['config' => $fileName]) + ) + ) + ); + } + + $content->addHtml($elem); + } } } diff --git a/public/css/module.less b/public/css/module.less index 1c2f57e..2d278d3 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -288,6 +288,22 @@ ul.bp { } } +// ** Node inspect broken files **/ +ul.broken-files { + .rounded-corners(); + padding: 1em; + margin: 1em 0; + border: 2px solid @state-warning; + font-size: 1.25em; + list-style: none; + + li { + padding-left: 1em; + font-weight: bold; + } +} +// ** END Node inspect broken files **/ + /** BEGIN Dashboard **/ .overview-dashboard { .header { From da0c72d5786320c2145611c726da5344aedea2f6 Mon Sep 17 00:00:00 2001 From: Sukhwinder Dhillon Date: Mon, 17 Jul 2023 15:13:19 +0200 Subject: [PATCH 3/5] DashboardAction: Use ipl-web's icon --- library/Businessprocess/Web/Component/DashboardAction.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/Businessprocess/Web/Component/DashboardAction.php b/library/Businessprocess/Web/Component/DashboardAction.php index 5ed1845..9bd3240 100644 --- a/library/Businessprocess/Web/Component/DashboardAction.php +++ b/library/Businessprocess/Web/Component/DashboardAction.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Businessprocess\Web\Component; use Icinga\Web\Url; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; +use ipl\Web\Widget\Icon; class DashboardAction extends BaseHtmlElement { @@ -19,7 +20,7 @@ class DashboardAction extends BaseHtmlElement } $this->add(Html::tag('a', $attributes) - ->add(Html::tag('i', ['class' => 'icon icon-' . $icon])) + ->add(new Icon($icon)) ->add(Html::tag('span', ['class' => 'header'], $title)) ->add($description)); } From 071f006b7d282524a327d9397b6b53aeb606d137 Mon Sep 17 00:00:00 2001 From: Sukhwinder Dhillon Date: Tue, 25 Jul 2023 10:01:43 +0200 Subject: [PATCH 4/5] AddNodeForm: Don't throw error while adding existing invalid config file --- application/forms/AddNodeForm.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/application/forms/AddNodeForm.php b/application/forms/AddNodeForm.php index 5ef11c7..448250c 100644 --- a/application/forms/AddNodeForm.php +++ b/application/forms/AddNodeForm.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Businessprocess\Forms; +use Exception; use Icinga\Module\Businessprocess\BpNode; use Icinga\Module\Businessprocess\BpConfig; use Icinga\Module\Businessprocess\Common\EnumList; @@ -471,7 +472,13 @@ class AddNodeForm extends QuickForm $bp = $this->bp; if ($differentFile) { - $bp = $this->storage->loadProcess($file); + try { + $bp = $this->storage->loadProcess($file); + } catch (Exception $e) { + $this->addError('Cannot add invalid config file'); + + return $list; + } } foreach ($bp->getNodes() as $node) { From 13330d3a44fea9bb9b5657033f9dd5ccc2c23f71 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 3 Aug 2023 10:55:54 +0200 Subject: [PATCH 5/5] Don't cast url to string if it's internally transformed again Also, the cast encodes the url as well, for use within HTML. This is not required if used in conjunction with ipl-html. --- application/controllers/NodeController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/controllers/NodeController.php b/application/controllers/NodeController.php index 80e6676..e5c657f 100644 --- a/application/controllers/NodeController.php +++ b/application/controllers/NodeController.php @@ -136,7 +136,7 @@ class NodeController extends Controller 'li', new Link( sprintf('%s (%s.conf)', $bpName, $fileName), - (string) Url::fromPath('businessprocess/process/show', ['config' => $fileName]) + \ipl\Web\Url::fromPath('businessprocess/process/show', ['config' => $fileName]) ) ) );