mirror of
https://github.com/Icinga/icingaweb2-module-businessprocess.git
synced 2025-12-31 18:59:34 -05:00
Merge branch 'next'
This commit is contained in:
commit
28fc19be33
146 changed files with 12217 additions and 3444 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1 +1,4 @@
|
|||
.idea/
|
||||
/debian
|
||||
/build
|
||||
/coverage
|
||||
|
|
|
|||
86
.gitlab-ci.yml
Normal file
86
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
stages:
|
||||
- Coding Standards
|
||||
- Unit-Tests
|
||||
- Build Packages
|
||||
|
||||
variables:
|
||||
BASE_VERSION: "2.0.0"
|
||||
VERSION_SUFFIX: "-b${CI_BUILD_ID}-${CI_BUILD_REF_SLUG}"
|
||||
|
||||
PSR2 CS Test:
|
||||
stage: Coding Standards
|
||||
tags:
|
||||
- xenial
|
||||
script:
|
||||
- phpcs --report-width=auto --report-full --report-gitblame --report-summary -p --standard=PSR2 --extensions=php --encoding=utf-8 -w -s library/Businessprocess/ application/ configuration.php run.php test
|
||||
|
||||
Ubuntu Xenial:
|
||||
stage: Unit-Tests
|
||||
tags:
|
||||
- xenial
|
||||
- businessprocess
|
||||
script:
|
||||
- phpunit --testdox --coverage-html=coverage || phpunit --verbose
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
name: code-coverage
|
||||
paths:
|
||||
- coverage/*
|
||||
|
||||
Debian Jessie:
|
||||
stage: Unit-Tests
|
||||
tags:
|
||||
- jessie
|
||||
- businessprocess
|
||||
script:
|
||||
- phpunit --testdox || phpunit --verbose
|
||||
|
||||
CentOS 6:
|
||||
stage: Unit-Tests
|
||||
tags:
|
||||
- centos6
|
||||
- businessprocess
|
||||
script:
|
||||
- phpunit --testdox || phpunit --verbose
|
||||
|
||||
CentOS 7:
|
||||
stage: Unit-Tests
|
||||
tags:
|
||||
- centos7
|
||||
- businessprocess
|
||||
script:
|
||||
- phpunit --testdox || phpunit --verbose
|
||||
|
||||
Xenial Packages:
|
||||
stage: Build Packages
|
||||
tags:
|
||||
- xenial
|
||||
- businessprocess
|
||||
script:
|
||||
- cp -a packaging/debian debian
|
||||
- dch --no-conf -U -M --empty -v "${BASE_VERSION}${VERSION_SUFFIX}-${CI_BUILD_REF:0:7}" "Automated build triggered by ${GITLAB_USER_ID} <${GITLAB_USER_EMAIL}>"
|
||||
- cp LICENSE debian/copyright
|
||||
- dpkg-buildpackage -us -uc
|
||||
- mkdir build
|
||||
- mv ../icingaweb2-module-businessprocess*.deb build/
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- build/*
|
||||
|
||||
Jessie Packages:
|
||||
stage: Build Packages
|
||||
tags:
|
||||
- jessie
|
||||
- businessprocess
|
||||
script:
|
||||
- cp -a packaging/debian debian
|
||||
- dch --no-conf -U -M --empty -v "${BASE_VERSION}${VERSION_SUFFIX}-${CI_BUILD_REF:0:7}" "Automated build triggered by ${GITLAB_USER_ID} <${GITLAB_USER_EMAIL}>"
|
||||
- cp LICENSE debian/copyright
|
||||
- dpkg-buildpackage -us -uc
|
||||
- mkdir build
|
||||
- mv ../icingaweb2-module-businessprocess*.deb build/
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- build/*
|
||||
|
|
@ -336,4 +336,4 @@ This General Public License does not permit incorporating your program into
|
|||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
Public License instead of this License.
|
||||
|
|
@ -2,37 +2,15 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess\Clicommands;
|
||||
|
||||
use Icinga\Cli\Command;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\HostNode;
|
||||
|
||||
class CheckCommand extends Command
|
||||
class CheckCommand extends ProcessCommand
|
||||
{
|
||||
protected $storage;
|
||||
|
||||
protected $hostColors = array(
|
||||
0 => array('black', 'lightgreen'),
|
||||
1 => array('black', 'lightred'),
|
||||
2 => array('black', 'brown'),
|
||||
99 => array('black', 'lightgray'),
|
||||
);
|
||||
|
||||
protected $serviceColors = array(
|
||||
0 => array('black', 'lightgreen'),
|
||||
1 => array('black', 'yellow'),
|
||||
2 => array('black', 'lightred'),
|
||||
3 => array('black', 'lightpurple'),
|
||||
99 => array('black', 'lightgray'),
|
||||
);
|
||||
|
||||
public function init()
|
||||
public function listActions()
|
||||
{
|
||||
$this->storage = new LegacyStorage($this->Config()->getSection('global'));
|
||||
return array('process');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a specific process
|
||||
* 'check process' is DEPRECATED, please use 'process check' instead
|
||||
*
|
||||
* USAGE
|
||||
*
|
||||
|
|
@ -40,75 +18,6 @@ class CheckCommand extends Command
|
|||
*/
|
||||
public function processAction()
|
||||
{
|
||||
$name = $this->params->get('config');
|
||||
if ($name === null) {
|
||||
$name = $this->getFirstProcessName();
|
||||
}
|
||||
|
||||
$bp = $this->storage->loadProcess($name);
|
||||
|
||||
if (null !== ($stateType = $this->params->get('state-type'))) {
|
||||
if ($stateType === 'soft') {
|
||||
$bp->useSoftStates();
|
||||
}
|
||||
if ($stateType === 'hard') {
|
||||
$bp->useHardStates();
|
||||
}
|
||||
}
|
||||
|
||||
$node = $bp->getNode($this->params->shift());
|
||||
$bp->retrieveStatesFromBackend();
|
||||
if ($bp->hasErrors()) {
|
||||
printf(
|
||||
"Checking Business Process %s failed: %s\n",
|
||||
$node->getAlias(),
|
||||
implode("\n", $bp->getErrors())
|
||||
);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
printf("Business Process %s: %s\n", $node->getStateName(), $node->getAlias());
|
||||
if ($this->params->shift('details')) {
|
||||
echo $this->renderProblemTree($node->getProblemTree(), $this->params->shift('colors'));
|
||||
}
|
||||
|
||||
exit($node->getState());
|
||||
}
|
||||
|
||||
protected function renderProblemTree($tree, $useColors = false, $depth = 0)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
foreach ($tree as $name => $subtree) {
|
||||
$node = $subtree['node'];
|
||||
|
||||
if ($node instanceof HostNode) {
|
||||
$colors = $this->hostColors[$node->getState()];
|
||||
} else {
|
||||
$colors = $this->serviceColors[$node->getState()];
|
||||
}
|
||||
|
||||
$state = sprintf('[%s]', $node->getStateName());
|
||||
if ($useColors) {
|
||||
$state = $this->screen->colorize($state, $colors[0], $colors[1]);
|
||||
}
|
||||
|
||||
$output .= sprintf(
|
||||
"%s%s %s %s\n",
|
||||
str_repeat(' ', $depth),
|
||||
$node instanceof BpNode ? $node->getOperator() : '-',
|
||||
$state,
|
||||
$node->getAlias()
|
||||
);
|
||||
$output .= $this->renderProblemTree($subtree['children'], $useColors, $depth + 1);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function getFirstProcessName()
|
||||
{
|
||||
$list = $this->storage->listProcesses();
|
||||
return key($list);
|
||||
$this->checkAction();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
153
application/clicommands/ProcessCommand.php
Normal file
153
application/clicommands/ProcessCommand.php
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Clicommands;
|
||||
|
||||
use Icinga\Cli\Command;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\HostNode;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\State\MonitoringState;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
|
||||
class ProcessCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var LegacyStorage
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
protected $hostColors = array(
|
||||
0 => array('black', 'lightgreen'),
|
||||
1 => array('lightgray', 'lightred'),
|
||||
2 => array('black', 'brown'),
|
||||
99 => array('black', 'lightgray'),
|
||||
);
|
||||
|
||||
protected $serviceColors = array(
|
||||
0 => array('black', 'lightgreen'),
|
||||
1 => array('black', 'yellow'),
|
||||
2 => array('lightgray', 'lightred'),
|
||||
3 => array('black', 'lightpurple'),
|
||||
99 => array('black', 'lightgray'),
|
||||
);
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->storage = new LegacyStorage($this->Config()->getSection('global'));
|
||||
}
|
||||
|
||||
/**
|
||||
* List all available process
|
||||
*
|
||||
* USAGE
|
||||
*
|
||||
* icingacli businessprocess list processes [options]
|
||||
*
|
||||
* OPTIONS
|
||||
*
|
||||
* --no-title Show only the process names and no related title
|
||||
*/
|
||||
public function listAction()
|
||||
{
|
||||
$noTitle = $this->params->shift('no-title');
|
||||
foreach ($this->storage->listProcessNames() as $key => $title) {
|
||||
if ($noTitle) {
|
||||
echo $key . "\n";
|
||||
} else {
|
||||
echo $title . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a specific process
|
||||
*
|
||||
* USAGE
|
||||
*
|
||||
* icingacli businessprocess process check <process> [options]
|
||||
*
|
||||
* OPTIONS
|
||||
*
|
||||
* --config <configname> Name of the config that contains <process>
|
||||
* --details Show problem details as a tree
|
||||
* --colors Show colored output
|
||||
* --state-type <type> Define which state type to look at. Could be
|
||||
* either soft or hard, overrides an eventually
|
||||
* configured default
|
||||
*/
|
||||
public function checkAction()
|
||||
{
|
||||
$name = $this->params->get('config');
|
||||
if ($name === null) {
|
||||
$name = $this->getFirstProcessName();
|
||||
}
|
||||
|
||||
$bp = $this->storage->loadProcess($name);
|
||||
|
||||
if (null !== ($stateType = $this->params->get('state-type'))) {
|
||||
if ($stateType === 'soft') {
|
||||
$bp->useSoftStates();
|
||||
}
|
||||
if ($stateType === 'hard') {
|
||||
$bp->useHardStates();
|
||||
}
|
||||
}
|
||||
|
||||
/** @var BpNode $node */
|
||||
$node = $bp->getNode($this->params->shift());
|
||||
MonitoringState::apply($bp);
|
||||
if ($bp->hasErrors()) {
|
||||
printf(
|
||||
"Checking Business Process %s failed: %s\n",
|
||||
$node->getAlias(),
|
||||
implode("\n", $bp->getErrors())
|
||||
);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
printf("Business Process %s: %s\n", $node->getStateName(), $node->getAlias());
|
||||
if ($this->params->shift('details')) {
|
||||
echo $this->renderProblemTree($node->getProblemTree(), $this->params->shift('colors'));
|
||||
}
|
||||
|
||||
exit($node->getState());
|
||||
}
|
||||
|
||||
protected function renderProblemTree($tree, $useColors = false, $depth = 0)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
foreach ($tree as $name => $subtree) {
|
||||
/** @var Node $node */
|
||||
$node = $subtree['node'];
|
||||
|
||||
if ($node instanceof HostNode) {
|
||||
$colors = $this->hostColors[$node->getState()];
|
||||
} else {
|
||||
$colors = $this->serviceColors[$node->getState()];
|
||||
}
|
||||
|
||||
$state = sprintf('[%s]', $node->getStateName());
|
||||
if ($useColors) {
|
||||
$state = $this->screen->colorize($state, $colors[0], $colors[1]);
|
||||
}
|
||||
|
||||
$output .= sprintf(
|
||||
"%s%s %s %s\n",
|
||||
str_repeat(' ', $depth),
|
||||
$node instanceof BpNode ? $node->getOperator() : '-',
|
||||
$state,
|
||||
$node->getAlias()
|
||||
);
|
||||
$output .= $this->renderProblemTree($subtree['children'], $useColors, $depth + 1);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function getFirstProcessName()
|
||||
{
|
||||
$list = $this->storage->listProcessNames();
|
||||
return key($list);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +1,20 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Module\Businessprocess\Controller;
|
||||
namespace Icinga\Module\Businessprocess\Controllers;
|
||||
|
||||
class Businessprocess_IndexController extends Controller
|
||||
use Icinga\Module\Businessprocess\Web\Controller;
|
||||
use Icinga\Module\Businessprocess\Web\Component\Dashboard;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show a welcome page if no process is available
|
||||
* Show an overview page
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$this->tabs()->add('welcome', array(
|
||||
'label' => $this->translate('Business Processes'),
|
||||
'url' => $this->getRequest()->getUrl()
|
||||
))->activate('welcome');
|
||||
|
||||
$configs = $this->storage()->listProcesses();
|
||||
|
||||
if (! empty($configs)) {
|
||||
// Redirect to show the first process if there is any
|
||||
$this->redirectNow(
|
||||
'businessprocess/process/show',
|
||||
array('config' => key($configs))
|
||||
);
|
||||
}
|
||||
|
||||
// Check back from time to time, maybe someone created a process
|
||||
$this->setAutorefreshInterval(30);
|
||||
$this->setTitle($this->translate('Business Process Overview'));
|
||||
$this->controls()->add($this->overviewTab());
|
||||
$this->content()->add(Dashboard::create($this->Auth(), $this->storage()));
|
||||
$this->setAutorefreshInterval(15);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,79 +1,60 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Module\Businessprocess\Controller;
|
||||
namespace Icinga\Module\Businessprocess\Controllers;
|
||||
|
||||
use Icinga\Module\Businessprocess\Renderer\Breadcrumb;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
use Icinga\Module\Businessprocess\Simulation;
|
||||
use Icinga\Module\Businessprocess\Forms\ProcessForm;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Module\Businessprocess\State\MonitoringState;
|
||||
use Icinga\Module\Businessprocess\Web\Controller;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
||||
/*
|
||||
config = <file>
|
||||
process = <node>
|
||||
|
||||
*/
|
||||
class Businessprocess_NodeController extends Controller
|
||||
class NodeController extends Controller
|
||||
{
|
||||
// rename to config
|
||||
public function editAction()
|
||||
public function impactAction()
|
||||
{
|
||||
$bp = $this->loadModifiedBpConfig();
|
||||
$node = $bp->getNode($this->getParam('node'));
|
||||
$detail = Url::fromPath(
|
||||
'businessprocess/node/edit',
|
||||
array(
|
||||
'config' => $this->view->configName,
|
||||
'node' => $node
|
||||
)
|
||||
$this->setAutorefreshInterval(10);
|
||||
$content = $this->content();
|
||||
$this->controls()->add(
|
||||
$this->singleTab($this->translate('Node Impact'))
|
||||
);
|
||||
$name = $this->params->get('name');
|
||||
$this->addTitle($this->translate('Business Impact (%s)'), $name);
|
||||
|
||||
$this->view->form = ProcessForm::construct()
|
||||
->setProcess($bp)
|
||||
->setSession($this->session())
|
||||
->setNode($node)
|
||||
->setRedirectUrl(
|
||||
sprintf(
|
||||
'businessprocess/process/show?config=%s&unlocked#!%s',
|
||||
$bp->getName(),
|
||||
$detail->getAbsoluteUrl()
|
||||
)
|
||||
)
|
||||
->handleRequest();
|
||||
foreach ($this->storage()->listProcessNames() as $configName) {
|
||||
$config = $this->storage()->loadProcess($configName);
|
||||
|
||||
$this->view->node = $node;
|
||||
}
|
||||
// TODO: Fix issues with children, they do not exist unless resolved :-/
|
||||
// This is a workaround:
|
||||
foreach ($config->getRootNodes() as $node) {
|
||||
$node->getState();
|
||||
}
|
||||
foreach ($config->getRootNodes() as $node) {
|
||||
$node->clearState();
|
||||
}
|
||||
|
||||
public function simulateAction()
|
||||
{
|
||||
$bp = $this->loadBpConfig();
|
||||
$nodename = $this->getParam('node');
|
||||
$node = $this->view->node = $bp->getNode($nodename);
|
||||
if (! $config->hasNode($name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->view->form = $this->loadForm('simulation')
|
||||
->setNode($node)
|
||||
->setSimulation(new Simulation($bp, $this->session()))
|
||||
->handleRequest();
|
||||
MonitoringState::apply($config);
|
||||
$simulation = new Simulation($config, $this->session());
|
||||
$config->applySimulation($simulation);
|
||||
|
||||
if ($this->view->form->succeeded()) {
|
||||
$this->render('empty');
|
||||
foreach ($config->getNode($name)->getPaths() as $path) {
|
||||
$node = array_pop($path);
|
||||
$renderer = new TileRenderer($config, $config->getNode($node));
|
||||
$renderer->setUrl(
|
||||
Url::fromPath(
|
||||
'businessprocess/process/show',
|
||||
array('config' => $configName)
|
||||
)
|
||||
)->setPath($path);
|
||||
|
||||
$bc = Breadcrumb::create($renderer);
|
||||
$bc->attributes()->set('data-base-target', '_next');
|
||||
$content->add($bc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addAction()
|
||||
{
|
||||
$bp = $this->loadBpConfig();
|
||||
|
||||
$redirectUrl = Url::fromPath(
|
||||
'businessprocess/process/show',
|
||||
array('config' => $bp->getName())
|
||||
);
|
||||
|
||||
$this->view->form = ProcessForm::construct()
|
||||
->setProcess($bp)
|
||||
->setSession($this->session())
|
||||
->setRedirectUrl($redirectUrl)
|
||||
->handleRequest();
|
||||
}
|
||||
|
||||
public function deleteAction()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,54 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Module\Businessprocess\Controller;
|
||||
use Icinga\Module\Businessprocess\ConfigDiff;
|
||||
namespace Icinga\Module\Businessprocess\Controllers;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\State\MonitoringState;
|
||||
use Icinga\Module\Businessprocess\Storage\ConfigDiff;
|
||||
use Icinga\Module\Businessprocess\Html\Element;
|
||||
use Icinga\Module\Businessprocess\Html\HtmlString;
|
||||
use Icinga\Module\Businessprocess\Html\HtmlTag;
|
||||
use Icinga\Module\Businessprocess\Html\Icon;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\Renderer\Breadcrumb;
|
||||
use Icinga\Module\Businessprocess\Renderer\Renderer;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
use Icinga\Module\Businessprocess\Renderer\TreeRenderer;
|
||||
use Icinga\Module\Businessprocess\Simulation;
|
||||
use Icinga\Module\Businessprocess\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
use Icinga\Module\Businessprocess\Forms\BpConfigForm;
|
||||
use Icinga\Module\Businessprocess\Forms\DeleteConfigForm;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyConfigRenderer;
|
||||
use Icinga\Module\Businessprocess\Web\Component\ActionBar;
|
||||
use Icinga\Module\Businessprocess\Web\Component\RenderedProcessActionBar;
|
||||
use Icinga\Module\Businessprocess\Web\Component\Tabs;
|
||||
use Icinga\Module\Businessprocess\Web\Controller;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Widget\Tabextension\DashboardAction;
|
||||
|
||||
|
||||
class Businessprocess_ProcessController extends Controller
|
||||
class ProcessController extends Controller
|
||||
{
|
||||
/** @var Renderer */
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* Create a new business process configuration
|
||||
*/
|
||||
public function createAction()
|
||||
{
|
||||
$this->setTitle($this->translate('Create a new business process'));
|
||||
$this->tabsForCreate()->activate('create');
|
||||
$this->assertPermission('businessprocess/create');
|
||||
|
||||
$this->view->form = BpConfigForm::construct()
|
||||
$title = $this->translate('Create a new business process');
|
||||
$this->setTitle($title);
|
||||
$this->controls()
|
||||
->add($this->tabsForCreate()->activate('create'))
|
||||
->add(HtmlTag::h1($title));
|
||||
|
||||
$this->content()->add(
|
||||
$this->loadForm('bpConfig')
|
||||
->setStorage($this->storage())
|
||||
->setRedirectUrl('businessprocess/process/show')
|
||||
->handleRequest();
|
||||
->setSuccessUrl('businessprocess/process/show')
|
||||
->handleRequest()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -32,84 +56,247 @@ class Businessprocess_ProcessController extends Controller
|
|||
*/
|
||||
public function uploadAction()
|
||||
{
|
||||
$this->setTitle($this->translate('Upload a business process config file'));
|
||||
$this->tabsForCreate()->activate('upload');
|
||||
$title = $this->translate('Upload a business process config file');
|
||||
$this->setTitle($title);
|
||||
$this->controls()
|
||||
->add($this->tabsForCreate()->activate('upload'))
|
||||
->add(HtmlTag::h1($title));
|
||||
|
||||
$this->content()->add(
|
||||
$this->loadForm('BpUpload')
|
||||
->setStorage($this->storage())
|
||||
->setSuccessUrl('businessprocess/process/show')
|
||||
->handleRequest()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a business process tree
|
||||
* Show a business process
|
||||
*/
|
||||
public function showAction()
|
||||
{
|
||||
$this->redirectIfConfigChosen();
|
||||
$bp = $this->loadModifiedBpConfig();
|
||||
$node = $this->getNode($bp);
|
||||
$this->redirectOnConfigSwitch();
|
||||
MonitoringState::apply($bp);
|
||||
$this->handleSimulations($bp);
|
||||
|
||||
$this->setTitle($this->translate('Business Process "%s"'), $bp->getTitle());
|
||||
|
||||
$renderer = $this->prepareRenderer($bp, $node);
|
||||
|
||||
if ($this->params->get('unlocked')) {
|
||||
$bp = $this->loadModifiedBpConfig();
|
||||
$bp->unlock();
|
||||
} else {
|
||||
$bp = $this->loadBpConfig();
|
||||
$renderer->unlock();
|
||||
}
|
||||
|
||||
$this->setTitle('Business Process "%s"', $bp->getTitle());
|
||||
$this->tabsForShow()->activate('show');
|
||||
|
||||
// Do not lock empty configs
|
||||
if ($bp->isEmpty() && ! $this->view->compact && $bp->isLocked()) {
|
||||
if ($bp->isEmpty() && $renderer->isLocked()) {
|
||||
$this->redirectNow($this->url()->with('unlocked', true));
|
||||
}
|
||||
|
||||
if ($node = $this->params->get('node')) {
|
||||
// Render a specific node
|
||||
$this->view->nodeName = $node;
|
||||
$this->view->bp = $bp->getNode($node);
|
||||
} else {
|
||||
// Render a single process
|
||||
$this->view->bp = $bp;
|
||||
if ($bp->hasWarnings()) {
|
||||
$this->view->warnings = $bp->getWarnings();
|
||||
}
|
||||
$this->prepareControls($bp, $renderer);
|
||||
$this->content()->addContent($this->showHints($bp));
|
||||
$this->content()->addContent($this->showWarnings($bp));
|
||||
$this->content()->add($renderer);
|
||||
$this->loadActionForm($bp, $node);
|
||||
$this->setDynamicAutorefresh();
|
||||
}
|
||||
|
||||
protected function prepareControls($bp, $renderer)
|
||||
{
|
||||
$controls = $this->controls();
|
||||
|
||||
if ($this->showFullscreen) {
|
||||
$controls->attributes()->add('class', 'want-fullscreen');
|
||||
$controls->add(
|
||||
Link::create(
|
||||
Icon::create('resize-small'),
|
||||
$this->url()->without('showFullscreen')->without('view'),
|
||||
null,
|
||||
array('style' => 'float: right')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$bp->retrieveStatesFromBackend();
|
||||
if (! ($this->showFullscreen || $this->view->compact)) {
|
||||
$controls->add($this->getProcessTabs($bp, $renderer));
|
||||
}
|
||||
if (! $this->view->compact) {
|
||||
$controls->add(Element::create('h1')->setContent($this->view->title));
|
||||
}
|
||||
$controls->add(Breadcrumb::create($renderer));
|
||||
if (! $this->showFullscreen && ! $this->view->compact) {
|
||||
$controls->add(
|
||||
new RenderedProcessActionBar($bp, $renderer, $this->Auth(), $this->url())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($bp->isLocked()) {
|
||||
$this->tabs()->extend(new DashboardAction());
|
||||
protected function getNode(BpConfig $bp)
|
||||
{
|
||||
if ($nodeName = $this->params->get('node')) {
|
||||
return $bp->getNode($nodeName);
|
||||
} else {
|
||||
$simulation = new Simulation($bp, $this->session());
|
||||
if ($this->params->get('dismissSimulations')) {
|
||||
Notification::success(
|
||||
sprintf(
|
||||
$this->translate('%d applied simulation(s) have been dropped'),
|
||||
$simulation->count()
|
||||
)
|
||||
);
|
||||
$simulation->clear();
|
||||
$this->redirectNow($this->url()->without('dismissSimulations')->without('unlocked'));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$bp->applySimulation($simulation);
|
||||
protected function prepareRenderer($bp, $node)
|
||||
{
|
||||
if ($this->renderer === null) {
|
||||
|
||||
if ($this->params->get('mode') === 'tree') {
|
||||
$renderer = new TreeRenderer($bp, $node);
|
||||
} else {
|
||||
$renderer = new TileRenderer($bp, $node);
|
||||
}
|
||||
$renderer->setUrl($this->url())
|
||||
->setPath($this->params->getValues('path'));
|
||||
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
if ($this->isXhr()) {
|
||||
$this->setAutorefreshInterval(10);
|
||||
} else {
|
||||
return $this->renderer;
|
||||
}
|
||||
|
||||
protected function getProcessTabs(BpConfig $bp, Renderer $renderer)
|
||||
{
|
||||
|
||||
$tabs = $this->singleTab($bp->getTitle());
|
||||
if ($renderer->isLocked()) {
|
||||
$tabs->extend(new DashboardAction());
|
||||
}
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
protected function handleSimulations(BpConfig $bp)
|
||||
{
|
||||
$simulation = new Simulation($bp, $this->session());
|
||||
|
||||
if ($this->params->get('dismissSimulations')) {
|
||||
Notification::success(
|
||||
sprintf(
|
||||
$this->translate('%d applied simulation(s) have been dropped'),
|
||||
$simulation->count()
|
||||
)
|
||||
);
|
||||
$simulation->clear();
|
||||
$this->redirectNow($this->url()->without('dismissSimulations')->without('unlocked'));
|
||||
}
|
||||
|
||||
$bp->applySimulation($simulation);
|
||||
}
|
||||
|
||||
protected function loadActionForm(BpConfig $bp, Node $node = null)
|
||||
{
|
||||
$action = $this->params->get('action');
|
||||
$form = null;
|
||||
if ($this->showFullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action === 'add') {
|
||||
$form = $this->loadForm('AddNode')
|
||||
->setProcess($bp)
|
||||
->setParentNode($node)
|
||||
->setSession($this->session())
|
||||
->handleRequest();
|
||||
} elseif ($action === 'delete') {
|
||||
$form =$this->loadForm('DeleteNode')
|
||||
->setProcess($bp)
|
||||
->setNode($bp->getNode($this->params->get('deletenode')))
|
||||
->setParentNode($node)
|
||||
->setSession($this->session())
|
||||
->handleRequest();
|
||||
} elseif ($action === 'edit') {
|
||||
$form =$this->loadForm('Process')
|
||||
->setProcess($bp)
|
||||
->setNode($bp->getNode($this->params->get('editnode')))
|
||||
->setSession($this->session())
|
||||
->handleRequest();
|
||||
} elseif ($action === 'simulation') {
|
||||
$form = $this->loadForm('simulation')
|
||||
->setNode($bp->getNode($this->params->get('simulationnode')))
|
||||
->setSimulation(new Simulation($bp, $this->session()))
|
||||
->handleRequest();
|
||||
}
|
||||
|
||||
if ($form) {
|
||||
$this->content()->prependContent(HtmlString::create((string) $form));
|
||||
}
|
||||
}
|
||||
|
||||
protected function setDynamicAutorefresh()
|
||||
{
|
||||
if (! $this->isXhr()) {
|
||||
// This will trigger the very first XHR refresh immediately on page
|
||||
// load. Please not that this may hammer the server in case we would
|
||||
// decide to use autorefreshInterval for HTML meta-refreshes also.
|
||||
$this->setAutorefreshInterval(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->params->get('mode') === 'toplevel') {
|
||||
$this->render('toplevel');
|
||||
if ($this->params->get('action')) {
|
||||
$this->setAutorefreshInterval(45);
|
||||
} else {
|
||||
$this->setAutorefreshInterval(10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a business process from a toplevel perspective
|
||||
*/
|
||||
public function toplevelAction()
|
||||
protected function showWarnings(BpConfig $bp)
|
||||
{
|
||||
$this->redirectIfConfigChosen();
|
||||
if ($bp->hasWarnings()) {
|
||||
$ul = Element::create('ul', array('class' => 'warning'));
|
||||
foreach ($bp->getWarnings() as $warning) {
|
||||
$ul->createElement('li')->addContent($warning);
|
||||
}
|
||||
|
||||
return $ul;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function showHints(BpConfig $bp)
|
||||
{
|
||||
$ul = Element::create('ul', array('class' => 'error'));
|
||||
foreach ($bp->getErrors() as $error) {
|
||||
$ul->createElement('li')->addContent($error);
|
||||
}
|
||||
if ($bp->hasChanges()) {
|
||||
$ul->createElement('li')->setSeparator(' ')->addContent(sprintf(
|
||||
$this->translate('This process has %d pending change(s).'),
|
||||
$bp->countChanges()
|
||||
))->addContent(
|
||||
Link::create(
|
||||
$this->translate('Store'),
|
||||
'businessprocess/process/config',
|
||||
array('config' => $bp->getName())
|
||||
)
|
||||
)->addContent(
|
||||
Link::create(
|
||||
$this->translate('Dismiss'),
|
||||
$this->url()->with('dismissChanges', true),
|
||||
null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($bp->hasSimulations()) {
|
||||
$ul->createElement('li')->setSeparator(' ')->addContent(sprintf(
|
||||
$this->translate('This process shows %d simulated state(s).'),
|
||||
$bp->countSimulations()
|
||||
))->addContent(Link::create(
|
||||
$this->translate('Dismiss'),
|
||||
$this->url()->with('dismissSimulations', true)
|
||||
));
|
||||
}
|
||||
|
||||
if ($ul->hasContent()) {
|
||||
return $ul;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -117,27 +304,73 @@ class Businessprocess_ProcessController extends Controller
|
|||
*/
|
||||
public function sourceAction()
|
||||
{
|
||||
$this->tabsForConfig()->activate('source');
|
||||
$bp = $this->loadModifiedBpConfig();
|
||||
$this->view->showDiff = $showDiff = (bool) $this->params->get('showDiff', false);
|
||||
|
||||
$this->view->source = $bp->toLegacyConfigString();
|
||||
$this->view->showDiff = (bool) $this->params->get('showDiff', false);
|
||||
|
||||
$this->view->source = LegacyConfigRenderer::renderConfig($bp);
|
||||
if ($this->view->showDiff) {
|
||||
$this->view->diff = ConfigDiff::create(
|
||||
$this->storage()->getSource($this->view->configName),
|
||||
$this->view->source
|
||||
);
|
||||
$this->view->title = sprintf(
|
||||
$title = sprintf(
|
||||
$this->translate('%s: Source Code Differences'),
|
||||
$bp->getTitle()
|
||||
);
|
||||
} else {
|
||||
$this->view->title = sprintf(
|
||||
$title = sprintf(
|
||||
$this->translate('%s: Source Code'),
|
||||
$bp->getTitle()
|
||||
);
|
||||
}
|
||||
|
||||
$actionBar = new ActionBar();
|
||||
$this->setTitle($title);
|
||||
$this->controls()
|
||||
->add($this->tabsForConfig()->activate('source'))
|
||||
->add(HtmlTag::h1($title))
|
||||
->add($actionBar);
|
||||
|
||||
if ($showDiff) {
|
||||
$actionBar->add(
|
||||
Link::create(
|
||||
$this->translate('Source'),
|
||||
$this->url()->without('showDiff'),
|
||||
null,
|
||||
array(
|
||||
'class' => 'icon-doc-text',
|
||||
'title' => $this->translate('Show source code'),
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$actionBar->add(
|
||||
Link::create(
|
||||
$this->translate('Diff'),
|
||||
$this->url()->with('showDiff', true),
|
||||
null,
|
||||
array(
|
||||
'class' => 'icon-flapping',
|
||||
'title' => $this->translate('Highlight changes'),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$actionBar->add(
|
||||
Link::create(
|
||||
$this->translate('Download'),
|
||||
'businessprocess/process/download',
|
||||
array('config' => $bp->getName()),
|
||||
array(
|
||||
'target' => '_blank',
|
||||
'class' => 'icon-download',
|
||||
'title' => $this->translate('Download process configuration')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->setViewScript('process/source');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,18 +379,17 @@ class Businessprocess_ProcessController extends Controller
|
|||
public function downloadAction()
|
||||
{
|
||||
$bp = $this->loadModifiedBpConfig();
|
||||
|
||||
header(
|
||||
$response = $this->getResponse();
|
||||
$response->setHeader(
|
||||
'Content-Disposition',
|
||||
sprintf(
|
||||
'Content-Disposition: attachment; filename="%s.conf";',
|
||||
'attachment; filename="%s.conf";',
|
||||
$bp->getName()
|
||||
)
|
||||
);
|
||||
header('Content-Type: text/plain');
|
||||
$response->setHeader('Content-Type', 'text/plain');
|
||||
|
||||
echo $bp->toLegacyConfigString();
|
||||
// Didn't have time to lookup how to correctly disable our renderers
|
||||
// TODO: no exit :)
|
||||
echo $this->storage()->render($bp);
|
||||
$this->doNotRender();
|
||||
}
|
||||
|
||||
|
|
@ -166,40 +398,38 @@ class Businessprocess_ProcessController extends Controller
|
|||
*/
|
||||
public function configAction()
|
||||
{
|
||||
$this->tabsForConfig()->activate('config');
|
||||
$bp = $this->loadModifiedBpConfig();
|
||||
|
||||
$this->setTitle(
|
||||
$title = sprintf(
|
||||
$this->translate('%s: Configuration'),
|
||||
$bp->getTitle()
|
||||
);
|
||||
$this->setTitle($title);
|
||||
$this->controls()
|
||||
->add($this->tabsForConfig()->activate('config'))
|
||||
->add(HtmlTag::h1($title));
|
||||
|
||||
$url = sprintf(
|
||||
'businessprocess/process/show?config=%s&unlocked#!%s',
|
||||
$bp->getName(),
|
||||
$this->getRequest()->getUrl()
|
||||
$url = Url::fromPath(
|
||||
'businessprocess/process/show?unlocked',
|
||||
array('config' => $bp->getName())
|
||||
);
|
||||
$this->content()->add(
|
||||
$this->loadForm('bpConfig')
|
||||
->setProcessConfig($bp)
|
||||
->setStorage($this->storage())
|
||||
->setSuccessUrl($url)
|
||||
->handleRequest()
|
||||
);
|
||||
$this->view->form = BpConfigForm::construct()
|
||||
->setProcessConfig($bp)
|
||||
->setStorage($this->storage())
|
||||
->setRedirectUrl($url)
|
||||
->handleRequest();
|
||||
|
||||
$this->view->deleteForm = DeleteConfigForm::construct()
|
||||
->setStorage($this->storage())
|
||||
->setController($this)
|
||||
->setBpConfig($bp)
|
||||
->handleRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to our URL plus the chosen config if someone switched the
|
||||
* config in the appropriate dropdown list
|
||||
*/
|
||||
protected function redirectIfConfigChosen()
|
||||
protected function redirectOnConfigSwitch()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($request->isPost() && $request->getPost('action') === 'switchConfig') {
|
||||
// We switched the process in the config dropdown list
|
||||
$params = array(
|
||||
'config' => $request->getPost('config')
|
||||
|
|
@ -216,6 +446,9 @@ class Businessprocess_ProcessController extends Controller
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tabs
|
||||
*/
|
||||
protected function tabsForCreate()
|
||||
{
|
||||
return $this->tabs()->add('create', array(
|
||||
|
|
|
|||
397
application/forms/AddNodeForm.php
Normal file
397
application/forms/AddNodeForm.php
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
use Icinga\Web\Session\SessionNamespace;
|
||||
|
||||
class AddNodeForm extends QuickForm
|
||||
{
|
||||
/** @var MonitoringBackend */
|
||||
protected $backend;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $bp;
|
||||
|
||||
/** @var BpNode */
|
||||
protected $parent;
|
||||
|
||||
protected $objectList = array();
|
||||
|
||||
protected $processList = array();
|
||||
|
||||
/** @var SessionNamespace */
|
||||
protected $session;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$view = $this->getView();
|
||||
if ($this->hasParentNode()) {
|
||||
$this->addHtml(
|
||||
'<h2>' . $view->escape(
|
||||
sprintf($this->translate('Add a node to %s'), $this->parent->getAlias())
|
||||
) . '</h2>'
|
||||
);
|
||||
} else {
|
||||
$this->addHtml(
|
||||
'<h2>' . $this->translate('Add a new root node') . '</h2>'
|
||||
);
|
||||
}
|
||||
|
||||
$type = $this->selectNodeType();
|
||||
switch ($type) {
|
||||
case 'host':
|
||||
$this->selectHost();
|
||||
break;
|
||||
case 'service':
|
||||
$this->selectService();
|
||||
break;
|
||||
case 'process':
|
||||
$this->selectProcess();
|
||||
break;
|
||||
case 'new-process':
|
||||
$this->addNewProcess();
|
||||
break;
|
||||
case null:
|
||||
$this->setSubmitLabel($this->translate('Next'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected function addNewProcess()
|
||||
{
|
||||
$this->addElement('text', 'name', array(
|
||||
'label' => $this->translate('Name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'This is the unique identifier of this process'
|
||||
),
|
||||
));
|
||||
|
||||
$this->addElement('text', 'alias', array(
|
||||
'label' => $this->translate('Title'),
|
||||
'description' => $this->translate(
|
||||
'Usually this title will be shown for this node. Equals name'
|
||||
. ' if not given'
|
||||
),
|
||||
));
|
||||
|
||||
$this->addElement('select', 'operator', array(
|
||||
'label' => $this->translate('Operator'),
|
||||
'required' => true,
|
||||
'multiOptions' => array(
|
||||
'&' => $this->translate('AND'),
|
||||
'|' => $this->translate('OR'),
|
||||
'!' => $this->translate('NOT'),
|
||||
'<' => $this->translate('DEG'),
|
||||
'1' => $this->translate('MIN 1'),
|
||||
'2' => $this->translate('MIN 2'),
|
||||
'3' => $this->translate('MIN 3'),
|
||||
'4' => $this->translate('MIN 4'),
|
||||
'5' => $this->translate('MIN 5'),
|
||||
'6' => $this->translate('MIN 6'),
|
||||
'7' => $this->translate('MIN 7'),
|
||||
'8' => $this->translate('MIN 8'),
|
||||
'9' => $this->translate('MIN 9'),
|
||||
)
|
||||
));
|
||||
|
||||
$this->addElement('select', 'display', array(
|
||||
'label' => $this->translate('Visualization'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'Where to show this process'
|
||||
),
|
||||
'value' => $this->hasParentNode() ? '0' : '1',
|
||||
'multiOptions' => array(
|
||||
'1' => $this->translate('Toplevel Process'),
|
||||
'0' => $this->translate('Subprocess only'),
|
||||
)
|
||||
));
|
||||
|
||||
$this->addElement('text', 'infoUrl', array(
|
||||
'label' => $this->translate('Info URL'),
|
||||
'description' => $this->translate(
|
||||
'URL pointing to more information about this node'
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
protected function selectNodeType()
|
||||
{
|
||||
$types = array();
|
||||
if ($this->hasParentNode()) {
|
||||
$types['host'] = $this->translate('Host');
|
||||
$types['service'] = $this->translate('Service');
|
||||
} elseif (! $this->hasProcesses()) {
|
||||
$this->addElement('hidden', 'node_type', array(
|
||||
'ignore' => true,
|
||||
'decorators' => array('ViewHelper'),
|
||||
'value' => 'new-process'
|
||||
));
|
||||
|
||||
return 'new-process';
|
||||
}
|
||||
|
||||
if ($this->hasProcesses()) {
|
||||
$types['process'] = $this->translate('Existing Process');
|
||||
}
|
||||
|
||||
$types['new-process'] = $this->translate('New Process Node');
|
||||
|
||||
$this->addElement('select', 'node_type', array(
|
||||
'label' => $this->translate('Node type'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'The node type you want to add'
|
||||
),
|
||||
'ignore' => true,
|
||||
'class' => 'autosubmit',
|
||||
'multiOptions' => $this->optionalEnum($types)
|
||||
));
|
||||
|
||||
return $this->getSentValue('node_type');
|
||||
}
|
||||
|
||||
protected function selectHost()
|
||||
{
|
||||
$this->addElement('multiselect', 'children', array(
|
||||
'label' => $this->translate('Hosts'),
|
||||
'required' => true,
|
||||
'size' => 8,
|
||||
'style' => 'width: 25em',
|
||||
'multiOptions' => $this->enumHostList(),
|
||||
'description' => $this->translate(
|
||||
'Hosts that should be part of this business process node'
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
protected function selectService()
|
||||
{
|
||||
$this->addHostElement();
|
||||
if ($host = $this->getSentValue('host')) {
|
||||
$this->addServicesElement($host);
|
||||
} else {
|
||||
$this->setSubmitLabel($this->translate('Next'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function addHostElement()
|
||||
{
|
||||
$this->addElement('select', 'host', array(
|
||||
'label' => $this->translate('Host'),
|
||||
'required' => true,
|
||||
'ignore' => true,
|
||||
'class' => 'autosubmit',
|
||||
'multiOptions' => $this->optionalEnum($this->enumHostForServiceList()),
|
||||
));
|
||||
}
|
||||
|
||||
protected function addServicesElement($host)
|
||||
{
|
||||
$this->addElement('multiselect', 'children', array(
|
||||
'label' => $this->translate('Services'),
|
||||
'required' => true,
|
||||
'size' => 8,
|
||||
'style' => 'width: 25em',
|
||||
'multiOptions' => $this->enumServiceList($host),
|
||||
'description' => $this->translate(
|
||||
'Services that should be part of this business process node'
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
protected function selectProcess()
|
||||
{
|
||||
$this->addElement('multiselect', 'children', array(
|
||||
'label' => $this->translate('Process nodes'),
|
||||
'required' => true,
|
||||
'size' => 8,
|
||||
'style' => 'width: 25em',
|
||||
'multiOptions' => $this->enumProcesses(),
|
||||
'description' => $this->translate(
|
||||
'Other processes that should be part of this business process node'
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MonitoringBackend $backend
|
||||
* @return $this
|
||||
*/
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpConfig $process
|
||||
* @return $this
|
||||
*/
|
||||
public function setProcess(BpConfig $process)
|
||||
{
|
||||
$this->bp = $process;
|
||||
$this->setBackend($process->getBackend());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode|null $node
|
||||
* @return $this
|
||||
*/
|
||||
public function setParentNode(BpNode $node = null)
|
||||
{
|
||||
$this->parent = $node;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasParentNode()
|
||||
{
|
||||
return $this->parent !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SessionNamespace $session
|
||||
* @return $this
|
||||
*/
|
||||
public function setSession(SessionNamespace $session)
|
||||
{
|
||||
$this->session = $session;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function enumHostForServiceList()
|
||||
{
|
||||
$names = $this->backend->select()->from('hostStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
))->order('host_name')->getQuery()->fetchColumn();
|
||||
|
||||
// fetchPairs doesn't seem to work when using the same column with
|
||||
// different aliases twice
|
||||
|
||||
return array_combine((array) $names, (array) $names);
|
||||
}
|
||||
|
||||
protected function enumHostList()
|
||||
{
|
||||
$names = $this->backend->select()->from('hostStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
))->order('host_name')->getQuery()->fetchColumn();
|
||||
|
||||
// fetchPairs doesn't seem to work when using the same column with
|
||||
// different aliases twice
|
||||
$res = array();
|
||||
$suffix = ';Hoststatus';
|
||||
foreach ($names as $name) {
|
||||
$res[$name . $suffix] = $name;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function enumServiceList($host)
|
||||
{
|
||||
$query = $this->backend->select()->from(
|
||||
'serviceStatus',
|
||||
array('service' => 'service_description')
|
||||
)->where('host_name', $host);
|
||||
$query->order('service_description');
|
||||
$names = $query->getQuery()->fetchColumn();
|
||||
|
||||
$services = array();
|
||||
foreach ($names as $name) {
|
||||
$services[$host . ';' . $name] = $name;
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
protected function hasProcesses()
|
||||
{
|
||||
return count($this->enumProcesses()) > 0;
|
||||
}
|
||||
|
||||
protected function enumProcesses()
|
||||
{
|
||||
$list = array();
|
||||
|
||||
foreach ($this->bp->getNodes() as $node) {
|
||||
if ($node instanceof BpNode) {
|
||||
// TODO: Blacklist parents
|
||||
$list[(string) $node] = (string) $node; // display name?
|
||||
}
|
||||
}
|
||||
|
||||
natsort($list);
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function fetchObjectList()
|
||||
{
|
||||
$this->objectList = array();
|
||||
$hosts = $this->backend->select()->from('hostStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'in_downtime' => 'host_in_downtime',
|
||||
'ack' => 'host_acknowledged',
|
||||
'state' => 'host_state'
|
||||
))->order('host_name')->getQuery()->fetchAll();
|
||||
|
||||
$services = $this->backend->select()->from('serviceStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'service' => 'service_description',
|
||||
'in_downtime' => 'service_in_downtime',
|
||||
'ack' => 'service_acknowledged',
|
||||
'state' => 'service_state'
|
||||
))->order('host_name')->order('service_description')->getQuery()->fetchAll();
|
||||
|
||||
foreach ($hosts as $host) {
|
||||
$this->objectList[$host->hostname] = array(
|
||||
$host->hostname . ';Hoststatus' => 'Host Status'
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($services as $service) {
|
||||
$this->objectList[$service->hostname][
|
||||
$service->hostname . ';' . $service->service
|
||||
] = $service->service;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$changes = ProcessChanges::construct($this->bp, $this->session);
|
||||
switch ($this->getValue('node_type')) {
|
||||
case 'host':
|
||||
case 'service':
|
||||
case 'process':
|
||||
$changes->addChildrenToNode($this->getValue('children'), $this->parent);
|
||||
break;
|
||||
case 'new-process':
|
||||
$properties = $this->getValues();
|
||||
unset($properties['name']);
|
||||
$properties['parentName'] = $this->parent->getName();
|
||||
$changes->createNode($this->getValue('name'), $properties);
|
||||
break;
|
||||
}
|
||||
|
||||
// Trigger session destruction to make sure it get's stored.
|
||||
// TODO: figure out why this is necessary, might be an unclean shutdown on redirect
|
||||
unset($changes);
|
||||
|
||||
parent::onSuccess();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,18 +3,19 @@
|
|||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Module\Businessprocess\Form;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Storage\Storage;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
|
||||
class BpConfigForm extends Form
|
||||
class BpConfigForm extends QuickForm
|
||||
{
|
||||
/** @var Storage */
|
||||
protected $storage;
|
||||
|
||||
protected $backend;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
protected $node;
|
||||
|
|
@ -23,47 +24,112 @@ class BpConfigForm extends Form
|
|||
|
||||
protected $processList = array();
|
||||
|
||||
protected $deleteButtonName;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$this->addElement('text', 'name', array(
|
||||
'label' => $this->translate('Name'),
|
||||
'label' => $this->translate('Name'),
|
||||
'required' => true,
|
||||
'validators' => array(
|
||||
array(
|
||||
'validator' => 'StringLength',
|
||||
'options' => array(
|
||||
'min' => 2,
|
||||
'max' => 40
|
||||
)
|
||||
),
|
||||
array(
|
||||
'validator' => 'Regex',
|
||||
'options' => array(
|
||||
'pattern' => '/^[a-zA-Z0-9](?:[a-zA-Z0-9 ._-]*)?[a-zA-Z0-9_]$/'
|
||||
)
|
||||
)
|
||||
),
|
||||
'description' => $this->translate(
|
||||
'This is the unique identifier of this process'
|
||||
),
|
||||
));
|
||||
|
||||
$this->addElement('text', 'title', array(
|
||||
$this->addElement('text', 'Title', array(
|
||||
'label' => $this->translate('Title'),
|
||||
'description' => $this->translate(
|
||||
'Usually this title will be shown for this process. Equals name'
|
||||
. ' if not given'
|
||||
. ' if not given'
|
||||
),
|
||||
));
|
||||
|
||||
$this->addElement('select', 'backend_name', array(
|
||||
$this->addElement('textarea', 'Description', array(
|
||||
'label' => $this->translate('Description'),
|
||||
'description' => $this->translate(
|
||||
'A slightly more detailed description for this process, about 100-150 characters long'
|
||||
),
|
||||
'rows' => 4,
|
||||
));
|
||||
|
||||
$this->addElement('select', 'Backend', array(
|
||||
'label' => $this->translate('Backend'),
|
||||
'description' => $this->translate(
|
||||
'Icinga Web Monitoring Backend where current object states for'
|
||||
. ' this process should be retrieved from'
|
||||
. ' this process should be retrieved from'
|
||||
),
|
||||
'multiOptions' => array(
|
||||
null => $this->translate('Use the configured default backend'),
|
||||
) + $this->listAvailableBackends()
|
||||
));
|
||||
|
||||
$this->addElement('select', 'state_type', array(
|
||||
$this->addElement('select', 'Statetype', array(
|
||||
'label' => $this->translate('State Type'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'Whether this process should be based on Icinga hard or soft states'
|
||||
),
|
||||
'multiOptions' => array(
|
||||
'hard' => $this->translate('Use HARD states'),
|
||||
'soft' => $this->translate('Use SOFT states'),
|
||||
'hard' => $this->translate('Use HARD states'),
|
||||
)
|
||||
));
|
||||
$this->addElement('submit', $this->translate('Store'));
|
||||
|
||||
$this->addElement('select', 'AddToMenu', array(
|
||||
'label' => $this->translate('Add to menu'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'Whether this process should be linked in the main Icinga Web 2 menu'
|
||||
),
|
||||
'multiOptions' => array(
|
||||
'yes' => $this->translate('Yes'),
|
||||
'no' => $this->translate('No'),
|
||||
)
|
||||
));
|
||||
|
||||
if ($this->config === null) {
|
||||
$this->setSubmitLabel(
|
||||
$this->translate('Add')
|
||||
);
|
||||
} else {
|
||||
$config = $this->config;
|
||||
|
||||
$meta = $config->getMetadata();
|
||||
foreach ($meta->getProperties() as $k => $v) {
|
||||
if ($el = $this->getElement($k)) {
|
||||
$el->setValue($v);
|
||||
}
|
||||
}
|
||||
$this->getElement('name')
|
||||
->setValue($config->getName())
|
||||
->setAttrib('readonly', true);
|
||||
|
||||
$this->setSubmitLabel(
|
||||
$this->translate('Store')
|
||||
);
|
||||
|
||||
$label = $this->translate('Delete');
|
||||
$el = $this->createElement('submit', $label, array(
|
||||
'data-base-target' => '_main'
|
||||
))->setLabel($label)->setDecorators(array('ViewHelper'));
|
||||
$this->deleteButtonName = $el->getName();
|
||||
$this->addElement($el);
|
||||
}
|
||||
}
|
||||
|
||||
protected function listAvailableBackends()
|
||||
|
|
@ -81,78 +147,69 @@ class BpConfigForm extends Form
|
|||
public function setProcessConfig($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->getElement('name')->setValue($config->getName());
|
||||
$this->getElement('name')->setAttrib('readonly', true);
|
||||
|
||||
if ($config->hasTitle()) {
|
||||
$this->getElement('title')->setValue($config->getTitle());
|
||||
}
|
||||
|
||||
if ($config->hasBackend()) {
|
||||
$this->getElement('backend_name')->setValue(
|
||||
$config->getBackend()->getName()
|
||||
);
|
||||
}
|
||||
|
||||
if ($config->usesSoftStates()) {
|
||||
$this->getElement('state_type')->setValue('soft');
|
||||
} else {
|
||||
$this->getElement('state_type')->setValue('hard');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function onRequest()
|
||||
{
|
||||
$name = $this->getValue('name');
|
||||
|
||||
if ($this->shouldBeDeleted()) {
|
||||
$this->config->clearAppliedChanges();
|
||||
$this->storage->deleteProcess($name);
|
||||
$this->setSuccessUrl('businessprocess');
|
||||
$this->redirectOnSuccess(sprintf('Process %s has been deleted', $name));
|
||||
}
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$name = $this->getValue('name');
|
||||
$title = $this->getValue('title');
|
||||
$backend = $this->getValue('backend');
|
||||
$name = $this->getValue('name');
|
||||
|
||||
if ($this->config === null) {
|
||||
// New config
|
||||
$config = new BusinessProcess();
|
||||
$config = new BpConfig();
|
||||
$config->setName($name);
|
||||
if ($title) {
|
||||
$config->setTitle($title);
|
||||
}
|
||||
if ($backend) {
|
||||
$config->setBackendName($backend);
|
||||
}
|
||||
if ($this->getValue('state_type') === 'soft') {
|
||||
$config->useSoftStates();
|
||||
} else {
|
||||
$config->useHardStates();
|
||||
}
|
||||
$this->storage->storeProcess($config);
|
||||
$config->clearAppliedChanges();
|
||||
$this->setRedirectUrl(
|
||||
$this->getRedirectUrl()->setParams(
|
||||
$config->getMetadata()->set('Owner', Auth::getInstance()->getUser()->getUsername());
|
||||
$this->setSuccessUrl(
|
||||
$this->getSuccessUrl()->setParams(
|
||||
array('config' => $name, 'unlocked' => true)
|
||||
)
|
||||
);
|
||||
$this->setSuccessMessage(sprintf('Process %s has been created', $name));
|
||||
|
||||
Notification::success(sprintf('Process %s has been created', $name));
|
||||
} else {
|
||||
// Existing config
|
||||
$config = $this->config;
|
||||
|
||||
if ($title) {
|
||||
$config->setTitle($title);
|
||||
}
|
||||
if ($backend) {
|
||||
$config->setBackendName($backend);
|
||||
}
|
||||
if ($this->getValue('state_type') === 'soft') {
|
||||
$config->useSoftStates();
|
||||
} else {
|
||||
$config->useHardStates();
|
||||
}
|
||||
|
||||
$this->storage->storeProcess($config);
|
||||
$config->clearAppliedChanges();
|
||||
$this->getRedirectUrl()->setParam('config', $name);
|
||||
Notification::success(sprintf('Process %s has been stored', $name));
|
||||
$this->setSuccessMessage(sprintf('Process %s has been stored', $name));
|
||||
}
|
||||
$meta = $config->getMetadata();
|
||||
foreach ($this->getValues() as $key => $value) {
|
||||
if ($value === null || $value === '') {
|
||||
continue;
|
||||
}
|
||||
if ($meta->hasKey($key)) {
|
||||
$meta->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->storage->storeProcess($config);
|
||||
$config->clearAppliedChanges();
|
||||
$this->setSuccessUrl('businessprocess/process/show', array('config' => $name));
|
||||
parent::onSuccess();
|
||||
}
|
||||
|
||||
public function hasDeleteButton()
|
||||
{
|
||||
return $this->deleteButtonName !== null;
|
||||
}
|
||||
|
||||
public function shouldBeDeleted()
|
||||
{
|
||||
if (! $this->hasDeleteButton()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->deleteButtonName;
|
||||
return $this->getSentValue($name) === $this->getElement($name)->getLabel();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
232
application/forms/BpUploadForm.php
Normal file
232
application/forms/BpUploadForm.php
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
use Icinga\Web\Notification;
|
||||
|
||||
class BpUploadForm extends QuickForm
|
||||
{
|
||||
/** @var LegacyStorage */
|
||||
protected $storage;
|
||||
|
||||
protected $backend;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
protected $node;
|
||||
|
||||
protected $objectList = array();
|
||||
|
||||
protected $processList = array();
|
||||
|
||||
protected $deleteButtonName;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$this->addElement('text', 'name', array(
|
||||
'label' => $this->translate('Name'),
|
||||
// 'required' => true,
|
||||
'description' => $this->translate(
|
||||
'This is the unique identifier of this process'
|
||||
),
|
||||
));
|
||||
|
||||
$this->addElement('text', 'title', array(
|
||||
'label' => $this->translate('Title'),
|
||||
'description' => $this->translate(
|
||||
'Usually this title will be shown for this process. Equals name'
|
||||
. ' if not given'
|
||||
),
|
||||
));
|
||||
|
||||
$this->addElement('select', 'backend_name', array(
|
||||
'label' => $this->translate('Backend'),
|
||||
'description' => $this->translate(
|
||||
'Icinga Web Monitoring Backend where current object states for'
|
||||
. ' this process should be retrieved from'
|
||||
),
|
||||
'multiOptions' => array(
|
||||
null => $this->translate('Use the configured default backend'),
|
||||
) + $this->listAvailableBackends()
|
||||
));
|
||||
|
||||
$this->addElement('select', 'state_type', array(
|
||||
'label' => $this->translate('State Type'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'Whether this process should be based on Icinga hard or soft states'
|
||||
),
|
||||
'multiOptions' => array(
|
||||
'hard' => $this->translate('Use HARD states'),
|
||||
'soft' => $this->translate('Use SOFT states'),
|
||||
)
|
||||
));
|
||||
|
||||
$this->setAttrib('enctype', 'multipart/form-data');
|
||||
|
||||
$tmpdir = sys_get_temp_dir();
|
||||
|
||||
$this->addElement('file', 'uploaded_file', array(
|
||||
'label' => $this->translate('File'),
|
||||
'destination' => $tmpdir,
|
||||
'required' => true,
|
||||
));
|
||||
|
||||
/** @var \Zend_Form_Element_File $el */
|
||||
$el = $this->getElement('uploaded_file');
|
||||
$el->setValueDisabled(true);
|
||||
|
||||
if ($this->config === null) {
|
||||
$this->setSubmitLabel(
|
||||
$this->translate('Add')
|
||||
);
|
||||
} else {
|
||||
$config = $this->config;
|
||||
|
||||
$this->getElement('name')
|
||||
->setValue($config->getName())
|
||||
->setAttrib('readonly', true);
|
||||
|
||||
if ($config->hasTitle()) {
|
||||
$this->getElement('title')->setValue($config->getTitle());
|
||||
}
|
||||
|
||||
if ($config->hasBackend()) {
|
||||
$this->getElement('backend_name')->setValue(
|
||||
$config->getBackend()->getName()
|
||||
);
|
||||
}
|
||||
if ($config->usesSoftStates()) {
|
||||
$this->getElement('state_type')->setValue('soft');
|
||||
} else {
|
||||
$this->getElement('state_type')->setValue('hard');
|
||||
}
|
||||
|
||||
$this->setSubmitLabel(
|
||||
$this->translate('Upload')
|
||||
);
|
||||
/*
|
||||
$label = $this->translate('Delete');
|
||||
$el = $this->createElement('submit', $label)
|
||||
->setLabel($label)
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$this->deleteButtonName = $el->getName();
|
||||
$this->addElement($el);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
protected function listAvailableBackends()
|
||||
{
|
||||
$keys = array_keys(Config::module('monitoring', 'backends')->toArray());
|
||||
return array_combine($keys, $keys);
|
||||
}
|
||||
|
||||
public function setStorage(LegacyStorage $storage)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setProcessConfig(BpConfig $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
|
||||
$tmpdir = sys_get_temp_dir();
|
||||
$tmpfile = tempnam($tmpdir, 'bpupload_');
|
||||
unlink($tmpfile);
|
||||
$values = $this->getValues();
|
||||
/** @var \Zend_Form_Element_File $el */
|
||||
$el = $this->getElement('uploaded_file');
|
||||
var_dump($el->getFileName());
|
||||
var_dump($tmpfile);
|
||||
$el->addFilter('Rename', $tmpfile);
|
||||
if (!$el->receive()) {
|
||||
print_r($el->file->getMessages());
|
||||
}
|
||||
echo file_get_contents($tmpfile);
|
||||
unlink($tmpfile);
|
||||
echo "DONE\n";
|
||||
exit;
|
||||
$name = $this->getValue('name');
|
||||
$title = $this->getValue('title');
|
||||
$backend = $this->getValue('backend');
|
||||
/*
|
||||
onSuccess:
|
||||
$uploadedData = $form->getValues();
|
||||
$fullFilePath = $form->file->getFileName();
|
||||
*/
|
||||
var_dump($this->getValues());
|
||||
|
||||
exit;
|
||||
|
||||
if ($this->config === null) {
|
||||
// New config
|
||||
$config = new BpConfig();
|
||||
$config->setName($name);
|
||||
if ($title) {
|
||||
$config->setTitle($title);
|
||||
}
|
||||
if ($backend) {
|
||||
$config->setBackendName($backend);
|
||||
}
|
||||
if ($this->getValue('state_type') === 'soft') {
|
||||
$config->useSoftStates();
|
||||
} else {
|
||||
$config->useHardStates();
|
||||
}
|
||||
$this->storage->storeProcess($config);
|
||||
$config->clearAppliedChanges();
|
||||
$this->setSuccessUrl(
|
||||
$this->getSuccessUrl()->setParams(
|
||||
array('config' => $name, 'unlocked' => true)
|
||||
)
|
||||
);
|
||||
|
||||
$this->redirectOnSuccess(sprintf('Process %s has been created', $name));
|
||||
} else {
|
||||
$config = $this->config;
|
||||
if ($title) {
|
||||
$config->setTitle($title);
|
||||
}
|
||||
if ($backend) {
|
||||
$config->setBackendName($backend);
|
||||
}
|
||||
if ($this->getValue('state_type') === 'soft') {
|
||||
$config->useSoftStates();
|
||||
} else {
|
||||
$config->useHardStates();
|
||||
}
|
||||
|
||||
$this->storage->storeProcess($config);
|
||||
$config->clearAppliedChanges();
|
||||
$this->getSuccessUrl()->setParam('config', $name);
|
||||
Notification::success(sprintf('Process %s has been stored', $name));
|
||||
}
|
||||
}
|
||||
|
||||
public function hasDeleteButton()
|
||||
{
|
||||
return $this->deleteButtonName !== null;
|
||||
}
|
||||
|
||||
public function shouldBeDeleted()
|
||||
{
|
||||
if (! $this->hasDeleteButton()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->deleteButtonName;
|
||||
return $this->getSentValue($name) === $this->getElement($name)->getLabel();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Module\Businessprocess\Form;
|
||||
use Icinga\Web\Notification;
|
||||
|
||||
class DeleteConfigForm extends Form
|
||||
{
|
||||
protected $storage;
|
||||
|
||||
protected $controller;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$this->addHidden('name');
|
||||
$this->addElement('submit', $this->translate('Delete this process'));
|
||||
}
|
||||
|
||||
public function setStorage($storage)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setController($controller)
|
||||
{
|
||||
$this->controller = $controller;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setBpConfig($bp)
|
||||
{
|
||||
$this->getElement('name')->setValue($bp->getName());
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$name = $this->getValue('name');
|
||||
$this->storage->deleteProcess($name);
|
||||
$this->setRedirectUrl('businessprocess');
|
||||
Notification::success(sprintf('Process %s has been deleted', $name));
|
||||
}
|
||||
}
|
||||
152
application/forms/DeleteNodeForm.php
Normal file
152
application/forms/DeleteNodeForm.php
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
use Icinga\Web\Session\SessionNamespace;
|
||||
|
||||
class DeleteNodeForm extends QuickForm
|
||||
{
|
||||
/** @var MonitoringBackend */
|
||||
protected $backend;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $bp;
|
||||
|
||||
/** @var Node */
|
||||
protected $node;
|
||||
|
||||
/** @var BpNode */
|
||||
protected $parentNode;
|
||||
|
||||
/** @var SessionNamespace */
|
||||
protected $session;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$node = $this->node;
|
||||
$view = $this->getView();
|
||||
$this->addHtml(
|
||||
'<h2>' . $view->escape(
|
||||
sprintf($this->translate('Delete "%s"'), $node->getAlias())
|
||||
) . '</h2>'
|
||||
);
|
||||
|
||||
$biLink = $view->qlink(
|
||||
$node->getAlias(),
|
||||
'businessprocess/node/impact',
|
||||
array('name' => $node->getName()),
|
||||
array('data-base-target' => '_next')
|
||||
);
|
||||
$this->addHtml(
|
||||
'<p>' . sprintf(
|
||||
$view->escape(
|
||||
$this->translate('Unsure? Show business impact of "%s"')
|
||||
),
|
||||
$biLink
|
||||
) . '</p>'
|
||||
);
|
||||
|
||||
if ($this->parentNode) {
|
||||
$yesMsg = sprintf(
|
||||
$this->translate('Delete from %s'),
|
||||
$this->parentNode->getAlias()
|
||||
);
|
||||
} else {
|
||||
$yesMsg = sprintf(
|
||||
$this->translate('Delete root node "%s"'),
|
||||
$this->node->getAlias()
|
||||
);
|
||||
}
|
||||
|
||||
$this->addElement('select', 'confirm', array(
|
||||
'label' => $this->translate('Are you sure?'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'Do you really want to delete this node?'
|
||||
),
|
||||
'multiOptions' => $this->optionalEnum(array(
|
||||
'no' => $this->translate('No'),
|
||||
'yes' => $yesMsg,
|
||||
'all' => sprintf($this->translate('Delete all occurrences of %s'), $node->getAlias()),
|
||||
))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MonitoringBackend $backend
|
||||
* @return $this
|
||||
*/
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpConfig $process
|
||||
* @return $this
|
||||
*/
|
||||
public function setProcess(BpConfig $process)
|
||||
{
|
||||
$this->bp = $process;
|
||||
$this->setBackend($process->getBackend());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
* @return $this
|
||||
*/
|
||||
public function setNode(Node $node)
|
||||
{
|
||||
$this->node = $node;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode|null $node
|
||||
* @return $this
|
||||
*/
|
||||
public function setParentNode(BpNode $node = null)
|
||||
{
|
||||
$this->parentNode = $node;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SessionNamespace $session
|
||||
* @return $this
|
||||
*/
|
||||
public function setSession(SessionNamespace $session)
|
||||
{
|
||||
$this->session = $session;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$changes = ProcessChanges::construct($this->bp, $this->session);
|
||||
|
||||
switch ($this->getValue('confirm')) {
|
||||
case 'yes':
|
||||
$changes->deleteNode($this->node, $this->path);
|
||||
break;
|
||||
case 'all':
|
||||
$changes->deleteNode($this->node);
|
||||
break;
|
||||
case 'no':
|
||||
$this->setSuccessMessage($this->translate('Well, maybe next time'));
|
||||
}
|
||||
// Trigger session desctruction to make sure it get's stored.
|
||||
// TODO: figure out why this is necessary, might be an unclean shutdown on redirect
|
||||
unset($changes);
|
||||
|
||||
parent::onSuccess();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,42 +2,55 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Form;
|
||||
use Icinga\Module\Businessprocess\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Session\SessionNamespace;
|
||||
|
||||
class ProcessForm extends Form
|
||||
class ProcessForm extends QuickForm
|
||||
{
|
||||
/** @var MonitoringBackend */
|
||||
protected $backend;
|
||||
|
||||
protected $process;
|
||||
/** @var BpConfig */
|
||||
protected $bp;
|
||||
|
||||
/** @var BpNode */
|
||||
protected $node;
|
||||
|
||||
protected $objectList = array();
|
||||
|
||||
protected $processList = array();
|
||||
|
||||
/** @var SessionNamespace */
|
||||
protected $session;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$this->addElement('text', 'name', array(
|
||||
'label' => $this->translate('Name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'This is the unique identifier of this process'
|
||||
),
|
||||
));
|
||||
if ($this->node === null) {
|
||||
$this->addElement('text', 'name', array(
|
||||
'label' => $this->translate('Name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate(
|
||||
'This is the unique identifier of this process'
|
||||
),
|
||||
));
|
||||
} else {
|
||||
$this->addHtml(
|
||||
'<h2>' . $this->getView()->escape(
|
||||
sprintf($this->translate('Modify "%s"'), $this->node->getAlias())
|
||||
) . '</h2>'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addElement('text', 'alias', array(
|
||||
'label' => $this->translate('Title'),
|
||||
'description' => $this->translate(
|
||||
'Usually this title will be shown for this node. Equals name'
|
||||
. ' if not given'
|
||||
. ' if not given'
|
||||
),
|
||||
));
|
||||
|
||||
|
|
@ -67,19 +80,8 @@ class ProcessForm extends Form
|
|||
'Where to show this process'
|
||||
),
|
||||
'multiOptions' => array(
|
||||
'0' => $this->translate('Subprocess only'),
|
||||
'1' => $this->translate('Toplevel Process'),
|
||||
)
|
||||
));
|
||||
|
||||
$this->addElement('multiselect', 'children', array(
|
||||
'label' => $this->translate('Process components'),
|
||||
'required' => true,
|
||||
'size' => 14,
|
||||
'style' => 'width: 25em;',
|
||||
'description' => $this->translate(
|
||||
'Hosts, services or other processes that should be part of this'
|
||||
. ' business process'
|
||||
'0' => $this->translate('Subprocess only'),
|
||||
)
|
||||
));
|
||||
|
||||
|
|
@ -90,96 +92,54 @@ class ProcessForm extends Form
|
|||
)
|
||||
));
|
||||
|
||||
$this->addElement('submit', $this->translate('Store'));
|
||||
}
|
||||
|
||||
public function setBackend($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
$this->fetchObjectList();
|
||||
$this->fillAvailableChildren();
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function fillAvailableChildren()
|
||||
{
|
||||
if (empty($this->processList)) {
|
||||
$children = $this->objectList;
|
||||
} else {
|
||||
$children = array(
|
||||
$this->translate('Other Business Processes') => $this->processList
|
||||
) + $this->objectList;
|
||||
}
|
||||
|
||||
$this->getElement('children')->setMultiOptions($children);
|
||||
}
|
||||
|
||||
public function setProcess($process)
|
||||
{
|
||||
$this->process = $process;
|
||||
$this->setBackend($process->getBackend());
|
||||
$this->processList = array();
|
||||
foreach ($process->getNodes() as $node) {
|
||||
if ($node instanceof BpNode) {
|
||||
// TODO: Blacklist parents
|
||||
$this->processList[(string) $node] = (string) $node; // display name?
|
||||
if ($node = $this->node) {
|
||||
if ($node->hasAlias()) {
|
||||
$this->getElement('alias')->setValue($node->getAlias());
|
||||
}
|
||||
$this->getElement('operator')->setValue($node->getOperator());
|
||||
$this->getElement('display')->setValue($node->getDisplay());
|
||||
if ($node->hasInfoUrl()) {
|
||||
$this->getElement('url')->setValue($node->getInfoUrl());
|
||||
}
|
||||
}
|
||||
natsort($this->processList);
|
||||
$this->fillAvailableChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MonitoringBackend $backend
|
||||
* @return $this
|
||||
*/
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setNode(Node $node)
|
||||
/**
|
||||
* @param BpConfig $process
|
||||
* @return $this
|
||||
*/
|
||||
public function setProcess(BpConfig $process)
|
||||
{
|
||||
$this->bp = $process;
|
||||
$this->setBackend($process->getBackend());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return $this
|
||||
*/
|
||||
public function setNode(BpNode $node)
|
||||
{
|
||||
$this->node = $node;
|
||||
|
||||
$this->setDefaults(array(
|
||||
'name' => (string) $node,
|
||||
'alias' => $node->hasAlias() ? $node->getAlias() : '',
|
||||
'display' => $node->getDisplay(),
|
||||
'operator' => $node->getOperator(),
|
||||
'url' => $node->getInfoUrl(),
|
||||
'children' => array_keys($node->getChildren())
|
||||
));
|
||||
$this->getElement('name')->setAttrib('readonly', true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function fetchObjectList()
|
||||
{
|
||||
$this->objectList = array();
|
||||
$hosts = $this->backend->select()->from('hostStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'in_downtime' => 'host_in_downtime',
|
||||
'ack' => 'host_acknowledged',
|
||||
'state' => 'host_state'
|
||||
))->order('host_name')->getQuery()->fetchAll();
|
||||
|
||||
$services = $this->backend->select()->from('serviceStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'service' => 'service_description',
|
||||
'in_downtime' => 'service_in_downtime',
|
||||
'ack' => 'service_acknowledged',
|
||||
'state' => 'service_state'
|
||||
))->order('host_name')->order('service_description')->getQuery()->fetchAll();
|
||||
|
||||
foreach ($hosts as $host) {
|
||||
$this->objectList[$host->hostname] = array(
|
||||
$host->hostname . ';Hoststatus' => 'Host Status'
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($services as $service) {
|
||||
$this->objectList[$service->hostname][
|
||||
$service->hostname . ';' . $service->service
|
||||
] = $service->service;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSession($session)
|
||||
/**
|
||||
* @param SessionNamespace $session
|
||||
* @return $this
|
||||
*/
|
||||
public function setSession(SessionNamespace $session)
|
||||
{
|
||||
$this->session = $session;
|
||||
return $this;
|
||||
|
|
@ -187,10 +147,9 @@ class ProcessForm extends Form
|
|||
|
||||
public function onSuccess()
|
||||
{
|
||||
$changes = ProcessChanges::construct($this->process, $this->session);
|
||||
$changes = ProcessChanges::construct($this->bp, $this->session);
|
||||
|
||||
$modifications = array();
|
||||
$children = $this->getValue('children');
|
||||
$alias = $this->getValue('alias');
|
||||
$operator = $this->getValue('operator');
|
||||
$display = $this->getValue('display');
|
||||
|
|
@ -201,7 +160,6 @@ class ProcessForm extends Form
|
|||
if (empty($alias)) {
|
||||
$alias = null;
|
||||
}
|
||||
ksort($children);
|
||||
// TODO: rename
|
||||
|
||||
if ($node = $this->node) {
|
||||
|
|
@ -212,9 +170,6 @@ class ProcessForm extends Form
|
|||
if ($operator !== $node->getOperator()) {
|
||||
$modifications['operator'] = $operator;
|
||||
}
|
||||
if ($children !== $node->getChildNames()) {
|
||||
$modifications['childNames'] = $children;
|
||||
}
|
||||
if ($url !== $node->getInfoUrl()) {
|
||||
$modifications['infoUrl'] = $url;
|
||||
}
|
||||
|
|
@ -225,7 +180,6 @@ class ProcessForm extends Form
|
|||
$modifications = array(
|
||||
'display' => $display,
|
||||
'operator' => $operator,
|
||||
'childNames' => $children,
|
||||
'infoUrl' => $url,
|
||||
'alias' => $alias,
|
||||
);
|
||||
|
|
@ -241,7 +195,7 @@ class ProcessForm extends Form
|
|||
Notification::success(
|
||||
sprintf(
|
||||
'Process %s has been modified',
|
||||
$this->process->getName()
|
||||
$this->bp->getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,56 +2,72 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
use Icinga\Module\Businessprocess\MonitoredNode;
|
||||
use Icinga\Module\Businessprocess\Simulation;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
|
||||
class SimulationForm extends QuickForm
|
||||
{
|
||||
/** @var MonitoredNode */
|
||||
protected $node;
|
||||
|
||||
/** @var MonitoredNode */
|
||||
protected $simulatedNode;
|
||||
|
||||
/** @var Simulation */
|
||||
protected $simulation;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$states = array(
|
||||
null => sprintf(
|
||||
$this->translate('Use current state (%s)'),
|
||||
$this->translate($this->node->getStateName())
|
||||
),
|
||||
'0' => $this->translate('OK'),
|
||||
'1' => $this->translate('WARNING'),
|
||||
'2' => $this->translate('CRITICAL'),
|
||||
'3' => $this->translate('UNKNOWN'),
|
||||
'99' => $this->translate('PENDING'),
|
||||
);
|
||||
$states = $this->enumStateNames();
|
||||
|
||||
// TODO: Fetch state from object
|
||||
if ($this->simulatedNode) {
|
||||
$states[$this->simulatedNode->getState()] . sprintf(' (%s)', $this->translate('Current simulation'));
|
||||
$simulatedState = $this->simulatedNode->getState();
|
||||
$states[$simulatedState] = sprintf(
|
||||
'%s (%s)',
|
||||
$this->node->getStateName($simulatedState),
|
||||
$this->translate('Current simulation')
|
||||
);
|
||||
$node = $this->simulatedNode;
|
||||
$hasSimulation = true;
|
||||
} else {
|
||||
$hasSimulation = false;
|
||||
$node = $this->node;
|
||||
}
|
||||
|
||||
$view = $this->getView();
|
||||
if ($hasSimulation) {
|
||||
$title = $this->translate('Modify simulation for %s');
|
||||
} else {
|
||||
$title = $this->translate('Add simulation for %s');
|
||||
}
|
||||
$this->addHtml(
|
||||
'<h2>'
|
||||
. $view->escape(sprintf($title, $node->getAlias()))
|
||||
. '</h2>'
|
||||
);
|
||||
|
||||
$this->addElement('select', 'state', array(
|
||||
'label' => $this->translate('State'),
|
||||
'multiOptions' => $states,
|
||||
'class' => 'autosubmit',
|
||||
'value' => $this->simulatedNode ? $node->getState() : null,
|
||||
));
|
||||
if (in_array($this->getSentValue('state'), array('0', '99'))) {
|
||||
return;
|
||||
}
|
||||
if ($hasSimulation || ctype_digit($this->getSentValue('state'))) {
|
||||
$this->addElement('checkbox', 'acknowledged', array(
|
||||
'label' => $this->translate('Acknowledged'),
|
||||
'value' => $node->isAcknowledged(),
|
||||
));
|
||||
|
||||
$this->addElement('checkbox', 'acknowledged', array(
|
||||
'label' => $this->translate('Acknowledged'),
|
||||
'value' => $node->isAcknowledged(),
|
||||
));
|
||||
|
||||
$this->addElement('checkbox', 'in_downtime', array(
|
||||
'label' => $this->translate('In downtime'),
|
||||
'value' => $node->isInDowntime(),
|
||||
));
|
||||
$this->addElement('checkbox', 'in_downtime', array(
|
||||
'label' => $this->translate('In downtime'),
|
||||
'value' => $node->isInDowntime(),
|
||||
));
|
||||
}
|
||||
|
||||
$this->setSubmitLabel($this->translate('Apply'));
|
||||
}
|
||||
|
|
@ -62,14 +78,14 @@ class SimulationForm extends QuickForm
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setSimulation($simulation)
|
||||
public function setSimulation(Simulation $simulation)
|
||||
{
|
||||
$this->simulation = $simulation;
|
||||
|
||||
$nodeName = (string) $this->node;
|
||||
if ($simulation->hasNode($nodeName)) {
|
||||
$name = $this->node->getName();
|
||||
if ($simulation->hasNode($name)) {
|
||||
$this->simulatedNode = clone($this->node);
|
||||
$s = $simulation->getNode($nodeName);
|
||||
$s = $simulation->getNode($name);
|
||||
$this->simulatedNode->setState($s->state)
|
||||
->setAck($s->acknowledged)
|
||||
->setDowntime($s->in_downtime)
|
||||
|
|
@ -81,7 +97,7 @@ class SimulationForm extends QuickForm
|
|||
|
||||
public function onSuccess()
|
||||
{
|
||||
$nodeName = (string) $this->node;
|
||||
$nodeName = $this->node->getName();
|
||||
|
||||
if (ctype_digit($this->getValue('state'))) {
|
||||
$this->notifySuccess($this->translate('Simulation has been set'));
|
||||
|
|
@ -95,5 +111,21 @@ class SimulationForm extends QuickForm
|
|||
$this->notifySuccess($this->translate('Simulation has been removed'));
|
||||
}
|
||||
}
|
||||
$this->redirectOnSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function enumStateNames()
|
||||
{
|
||||
$states = array(
|
||||
null => sprintf(
|
||||
$this->translate('Use current state (%s)'),
|
||||
$this->translate($this->node->getStateName())
|
||||
)
|
||||
) + $this->node->enumStateNames();
|
||||
|
||||
return $states;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,101 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Forms;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Request;
|
||||
|
||||
class CreateConfigForm extends Form
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$this->addElement('text', 'name', array(
|
||||
'label' => $this->translate('Name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('This is the unique identifier of this process'),
|
||||
));
|
||||
|
||||
$this->addElement('text', 'title', array(
|
||||
'label' => $this->translate('Title'),
|
||||
'description' => $this->translate('Usually this title will be shown for this process. Equals name if not given'),
|
||||
));
|
||||
|
||||
$this->addElement('select', 'backend_name', array(
|
||||
'label' => $this->translate('Backend'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Icinga Web Monitoring Backend where current object states for this process should be retrieved from'),
|
||||
'multiOptions' => array(
|
||||
null => $this->translate('Use current default backend'),
|
||||
) + $this->listAvailableBackends()
|
||||
));
|
||||
|
||||
$this->addElement('select', 'state_type', array(
|
||||
'label' => $this->translate('State Type'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Whether this process should be based on Icinga hard or soft states'),
|
||||
'multiOptions' => array(
|
||||
'hard' => $this->translate('Use HARD states'),
|
||||
'soft' => $this->translate('Use SOFT states'),
|
||||
)
|
||||
));
|
||||
$this->addElement('submit', $this->translate('Store'));
|
||||
}
|
||||
|
||||
protected function listAvailableBackends()
|
||||
{
|
||||
$keys = array_keys(Config::module('monitoring', 'backends')->toArray());
|
||||
return array_combine($keys, $keys);
|
||||
}
|
||||
|
||||
public function setBackend($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setProcessConfig($config)
|
||||
{
|
||||
$this->process = $config;
|
||||
$this->getElement('name')->setValue($config->getName());
|
||||
|
||||
if ($config->hasTitle()) {
|
||||
$this->getElement('title')->setValue($config->getTitle());
|
||||
}
|
||||
|
||||
if ($config->hasBackend()) {
|
||||
$this->getElement('backend_name')->setValue($config->getBackend()->getName());
|
||||
}
|
||||
|
||||
if ($config->usesSoftStates()) {
|
||||
$this->getElement('state_type')->setValue('soft');
|
||||
} else {
|
||||
$this->getElement('state_type')->setValue('hard');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSession($session)
|
||||
{
|
||||
$this->session = $session;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
/*
|
||||
$storage->storeProcess($bp);
|
||||
$modifications = $this->session->get('modifications', array());
|
||||
$node = $this->process->getNode($this->getValue('name'));
|
||||
$node->setChildNames($this->getValue('children'));
|
||||
$node->setOperator($this->getValue('operator'));
|
||||
$modifications[$this->process->getName()] = $this->process->toLegacyConfigString();
|
||||
$this->session->set('modifications', $modifications);
|
||||
$message = 'Process %s has been modified';
|
||||
Notification::success(sprintf($message, $this->process->getName()));
|
||||
*/
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1,135 +1,258 @@
|
|||
# Icinga Web 2 - Head for multiple monitoring backends.
|
||||
# Copyright (C) 2015 Icinga Development Team
|
||||
# Copyright (C) 2016 Icinga Development Team
|
||||
# This file is distributed under the same license as Businessprocess Module.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Businessprocess Module (2.0.0-beta1)\n"
|
||||
"Project-Id-Version: Businessprocess Module (2.0.0)\n"
|
||||
"Report-Msgid-Bugs-To: dev@icinga.org\n"
|
||||
"POT-Creation-Date: 2015-03-16 06:19+0100\n"
|
||||
"PO-Revision-Date: 2015-03-16 09:04+0100\n"
|
||||
"POT-Creation-Date: 2016-12-12 13:32+0100\n"
|
||||
"PO-Revision-Date: 2016-12-12 13:48+0100\n"
|
||||
"Last-Translator: Thomas Gelf <thomas@gelf.net>\n"
|
||||
"Language: de_DE\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 1.5.4\n"
|
||||
"Language-Team: \n"
|
||||
"X-Generator: Poedit 1.8.7.1\n"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:83
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:174
|
||||
#, php-format
|
||||
msgid "%d applied simulation(s) have been dropped"
|
||||
msgstr "%d angewendete Simulation(en) wurde(n) entfernt"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Controller.php:73
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Controller.php:187
|
||||
#, php-format
|
||||
msgid "%d pending change(s) have been dropped"
|
||||
msgstr "%d vorgenommene Änderung(en) wurde(n) verworfen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:165
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:349
|
||||
#, php-format
|
||||
msgid "%s: Configuration"
|
||||
msgstr "%s: Konfiguration"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:129
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:313
|
||||
#, php-format
|
||||
msgid "%s: Source Code"
|
||||
msgstr "%s: Quellcode"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:124
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:308
|
||||
#, php-format
|
||||
msgid "%s: Source Code Differences"
|
||||
msgstr "%s: Quellcode Unterschiede"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:48
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/ProvidedHook/Director/DataType/BusinessProcess.php:17
|
||||
msgid "(no process config chosen)"
|
||||
msgstr "(keine Prozess-Konfiguration gewählt)"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Form/QuickBaseForm.php:113
|
||||
msgid "- please choose -"
|
||||
msgstr "- bitte wählen -"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:50
|
||||
msgid ""
|
||||
"A slightly more detailed description for this process, about 100-150 "
|
||||
"characters long"
|
||||
msgstr ""
|
||||
"Eine etwas detailliertere Beschreibung dieses Prozesses, etwa 100-150 "
|
||||
"Zeichen lang"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:53
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:76
|
||||
msgid "AND"
|
||||
msgstr "UND"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:42
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:62
|
||||
msgid "Acknowledged"
|
||||
msgstr "Bestätigt"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/node/add.phtml:8
|
||||
msgid "Add new process node"
|
||||
msgstr "Neuen Knoten hinzufügen"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:92
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:86
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TileRenderer.php:91
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TreeRenderer.php:241
|
||||
msgid "Add"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:49
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TileRenderer.php:89
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TreeRenderer.php:246
|
||||
msgid "Add a new business process node"
|
||||
msgstr "Neuen Business-Prozess hinzufügen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:88
|
||||
msgid "Add children"
|
||||
msgstr "Nachfolger hinzufügen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:43
|
||||
#, php-format
|
||||
msgid "Add simulation for %s"
|
||||
msgstr "Simulation für %s hinzufügen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:79
|
||||
msgid "Add to menu"
|
||||
msgstr "Zum Menü hinzufügen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/configuration.php:50
|
||||
msgid "Allow to create whole new process configuration (files)"
|
||||
msgstr "Erlaube das erstellen einer neuen Prozess-Konfiguration (Datei)"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/configuration.php:54
|
||||
msgid "Allow to modify process definitions, to add and remove nodes"
|
||||
msgstr ""
|
||||
"Erlaubt es Prozessdefinitionen zu modifizieren, sowie Knoten hinzuzufügen "
|
||||
"und zu entfernen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/configuration.php:46
|
||||
msgid ""
|
||||
"Allow to see all available processes, regardless of configured restrictions"
|
||||
msgstr ""
|
||||
"Erlaubt es, alle verfügbaren Prozesse unabhängig von konfigurierten "
|
||||
"Restriktionen zu sehen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:96
|
||||
msgid "Another process"
|
||||
msgstr "Ein anderer Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:72
|
||||
msgid "Apply"
|
||||
msgstr "Anwenden"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/index/index.phtml:8
|
||||
#, php-format
|
||||
msgid ""
|
||||
"As no business process has been defined yet you might want to create a %s or "
|
||||
"upload an %s."
|
||||
msgstr ""
|
||||
"Nachdem noch kein Business-Prozess definiert wurde, möchtest du vermutlich "
|
||||
"einen %s erstellen oder einen %s hochladen."
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/DeleteNodeForm.php:32
|
||||
msgid "Are you sure?"
|
||||
msgstr "Bist du sicher?"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:47
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:27
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:56
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:48
|
||||
msgid "Backend"
|
||||
msgstr "Backend"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:206
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:384
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Controller.php:128
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Controller.php:139
|
||||
msgid "Business Process"
|
||||
msgstr "Business-Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/configuration.php:4
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/IndexController.php:13
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:81
|
||||
#, php-format
|
||||
msgid "Business Process \"%s\""
|
||||
msgstr "Businessprozesse \"%s\""
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/IndexController.php:15
|
||||
msgid "Business Process Overview"
|
||||
msgstr "Businessprozessübersicht"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/configuration.php:5
|
||||
msgid "Business Processes"
|
||||
msgstr "Business-Prozesse"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:31
|
||||
msgid "CRITICAL"
|
||||
msgstr "KRITISCH"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:75
|
||||
msgid "Config"
|
||||
msgstr "Konfiguration"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/index/index.phtml:6
|
||||
msgid "Configure your first business process"
|
||||
msgstr "Konfiguriere deinen ersten Business-Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BusinessProcess.php:297
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BusinessProcess.php:316
|
||||
#, php-format
|
||||
msgid "Could not retrieve process state: %s"
|
||||
msgstr "Konnte den Prozess-Status nicht ermitteln: %s"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:214
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:395
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:55
|
||||
msgid "Create"
|
||||
msgstr "Erstelle"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:21
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:56
|
||||
msgid "Create a new Business Process configuration"
|
||||
msgstr "Erstelle eine neue Businessprozesskonfiguration"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:37
|
||||
msgid "Create a new business process"
|
||||
msgstr "Neuen Business-Prozess erstellen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/DeleteConfigForm.php:18
|
||||
msgid "Delete this process"
|
||||
msgstr "Lösche diesen Prozess"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:30
|
||||
msgid "Current simulation"
|
||||
msgstr "Aktuelle Simulation"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/show.phtml:40
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/show.phtml:51
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:79
|
||||
msgid "DEG"
|
||||
msgstr "DEG"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:111
|
||||
msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TileRenderer/NodeTile.php:159
|
||||
msgid "Delete this node"
|
||||
msgstr "Lösche diesen Knoten"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:48
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:267
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:279
|
||||
msgid "Dismiss"
|
||||
msgstr "Verwerfen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/DeleteNodeForm.php:35
|
||||
msgid "Do you really want to delete this node"
|
||||
msgstr "Möchtest du diesen Knoten wirklich löschen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/source.phtml:6
|
||||
msgid "Download process configuration"
|
||||
msgstr "Prozess-Konfiguration herunterladen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:125
|
||||
msgid "Existing Process"
|
||||
msgstr "Existierender Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:97
|
||||
msgid "External process"
|
||||
msgstr "Externer Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:75
|
||||
msgid "File"
|
||||
msgstr "Datei"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Form/QuickForm.php:390
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Form/QuickForm.php:415
|
||||
msgid "Form has successfully been sent"
|
||||
msgstr "Das Formular wurde erfolgreich versandt"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:47
|
||||
msgid ""
|
||||
"From here you can reach all your defined Business Process configurations, "
|
||||
"create new or modify existing ones"
|
||||
msgstr ""
|
||||
"Von hier kannst du alle definierten Businessprozesskonfigurationen "
|
||||
"erreichen, neue erstellen oder bestehende bearbeiten"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:89
|
||||
msgid "Fullscreen"
|
||||
msgstr "Vollbild"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/source.phtml:10
|
||||
msgid "Highlight changes"
|
||||
msgstr "Änderungen hervorheben"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:80
|
||||
msgid ""
|
||||
"Hosts, services or other processes that should be part of this business "
|
||||
"process"
|
||||
msgstr ""
|
||||
"Hosts, Services oder andere Prozesse welche Teil dieses Business-Prozesses "
|
||||
"sein sollen"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:94
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:135
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:120
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:171
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:49
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:29
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:121
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:147
|
||||
msgid "Hosts"
|
||||
msgstr "Hosts"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:127
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:153
|
||||
msgid "Hosts that should be part of this business process node"
|
||||
msgstr "Hosts welche Teil dieses Business-Prozesses sein sollen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:58
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:50
|
||||
msgid ""
|
||||
"Icinga Web Monitoring Backend where current object states for this process "
|
||||
"should be retrieved from"
|
||||
|
|
@ -137,51 +260,65 @@ msgstr ""
|
|||
"Das Icinga Web Monitoring Backend von welchem die Status-Informationen für "
|
||||
"diesen Prozess bezogen werden sollen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:46
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:67
|
||||
msgid "In downtime"
|
||||
msgstr "In Downtime"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:86
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:81
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:106
|
||||
msgid "Info URL"
|
||||
msgstr "Info-URL"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/show.phtml:13
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:61
|
||||
msgid "Lock"
|
||||
msgstr "Sperren"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:66
|
||||
msgid "Lock this process"
|
||||
msgstr "Sperre diesen Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:50
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:56
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:80
|
||||
msgid "MIN 1"
|
||||
msgstr "MIN 1"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:51
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:57
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:81
|
||||
msgid "MIN 2"
|
||||
msgstr "MIN 2"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:52
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:58
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:82
|
||||
msgid "MIN 3"
|
||||
msgstr "MIN 3"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:53
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:59
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:83
|
||||
msgid "MIN 4"
|
||||
msgstr "MIN 4"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:54
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:60
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:84
|
||||
msgid "MIN 5"
|
||||
msgstr "MIN 5"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:55
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:61
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:85
|
||||
msgid "MIN 6"
|
||||
msgstr "MIN 6"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:56
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:62
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:86
|
||||
msgid "MIN 7"
|
||||
msgstr "MIN 7"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:57
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:63
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:87
|
||||
msgid "MIN 8"
|
||||
msgstr "MIN 8"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:58
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:64
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:88
|
||||
msgid "MIN 9"
|
||||
msgstr "MIN 9"
|
||||
|
||||
|
|
@ -190,225 +327,359 @@ msgstr "MIN 9"
|
|||
msgid "Modify process node: %s"
|
||||
msgstr "Bearbeite Knoten: %s"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BpNode.php:268
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:41
|
||||
#, php-format
|
||||
msgid "Modify simulation for %s"
|
||||
msgstr "Bearbeite die Simulation für %s"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TileRenderer/NodeTile.php:136
|
||||
msgid "Modify this business process node"
|
||||
msgstr "Bearbeite diesen Prozessknoten"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TreeRenderer.php:199
|
||||
msgid "Modify this node"
|
||||
msgstr "Bearbeite diesen Knoten"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Node.php:350
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:80
|
||||
msgid "Modify this process"
|
||||
msgstr "Bearbeite diesen Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TreeRenderer.php:222
|
||||
msgid "More information"
|
||||
msgstr "Weitere Informationen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:31
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:16
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:29
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:55
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:78
|
||||
msgid "NOT"
|
||||
msgstr "NICHT"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:32
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:34
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:57
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:32
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BusinessProcess.php:519
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BpNode.php:276
|
||||
#, php-format
|
||||
msgid "Nesting error detected: %s"
|
||||
msgstr "Verschachtelungsfehler erkannt: %s"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:128
|
||||
msgid "New Process Node"
|
||||
msgstr "Neuen Prozess-Knoten hinzufügen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:47
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:164
|
||||
msgid "Next"
|
||||
msgstr "Weiter"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:86
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/DeleteNodeForm.php:39
|
||||
msgid "No"
|
||||
msgstr "Nein"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:77
|
||||
msgid "No Business Process has been defined for you"
|
||||
msgstr "Es wurde noch kein Business-Prozess für dich definiert"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BusinessProcess.php:693
|
||||
#, php-format
|
||||
msgid "No business process nodes for \"%s\" have been defined yet"
|
||||
msgstr "Es wurden noch keine Business-Prozess Knoten für \"%s\" definiert"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BusinessProcess.php:467
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Controller.php:205
|
||||
#, php-format
|
||||
msgid "No such process config: \"%s\""
|
||||
msgstr "Keine entsprechende Prozesskonfiguration gefunden: \"%s\""
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BusinessProcess.php:575
|
||||
#, php-format
|
||||
msgid "Node \"%s\" has been defined twice"
|
||||
msgstr "Der Knoden \"%s\" wurde doppelt definiert"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:29
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:131
|
||||
msgid "Node type"
|
||||
msgstr "Knotentyp"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:49
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:76
|
||||
msgid "Not available"
|
||||
msgstr "NIcht verfügbar"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:54
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:77
|
||||
msgid "OR"
|
||||
msgstr "ODER"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:45
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:50
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:73
|
||||
msgid "Operator"
|
||||
msgstr "Operator"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:109
|
||||
msgid "Other Business Processes"
|
||||
msgstr "Andere Business-Prozesse"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:166
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:202
|
||||
msgid "Other processes that should be part of this business process node"
|
||||
msgstr "Andere Prozesse welche Teil dieses Business-Prozesses sein sollen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:33
|
||||
msgid "PENDING"
|
||||
msgstr "PENDING"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/BusinessProcess.php:538
|
||||
#, php-format
|
||||
msgid "Parser waring on %s:%s: %s"
|
||||
msgstr "Parse-Warnung an %s:%s: %s"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:38
|
||||
msgid "Plugin output"
|
||||
msgstr "Plugin-Ausgabe"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:225
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:406
|
||||
msgid "Process Configuration"
|
||||
msgstr "Prozess-Konfiguration"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:75
|
||||
msgid "Process components"
|
||||
msgstr "Prozess-Komponenten"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:160
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:196
|
||||
msgid "Process nodes"
|
||||
msgstr "Prozess-Knoten"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/configuration.php:3
|
||||
msgid "Reporting"
|
||||
msgstr "Reporting"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:95
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:121
|
||||
msgid "Service"
|
||||
msgstr "Service"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:146
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:182
|
||||
msgid "Services"
|
||||
msgstr "Services"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:152
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:188
|
||||
msgid "Services that should be part of this business process node"
|
||||
msgstr "Services welche Teil dieses Business-Prozesses sein sollen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/configuration.php:26
|
||||
msgid "Show all"
|
||||
msgstr "Alle anzeigen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/source.phtml:8
|
||||
msgid "Show source code"
|
||||
msgstr "Quellcode anzeigen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:86
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TileRenderer/NodeTile.php:151
|
||||
msgid "Show the business impact of this node by simulating a specific state"
|
||||
msgstr ""
|
||||
"Zeige den Business-Impact dieses Knoten durch Simulation eines gewünschten "
|
||||
"Zustandes"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TileRenderer/NodeTile.php:142
|
||||
msgid "Show this subtree as a tree"
|
||||
msgstr "Zeige diesen Teilbaum als eigenen Baum"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Renderer/TreeRenderer.php:212
|
||||
msgid "Simulate a specific state"
|
||||
msgstr "Einen bestimmten Zustand simulieren"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:111
|
||||
msgid "Simulation has been removed"
|
||||
msgstr "Simulation wurde entfernt"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:89
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:103
|
||||
msgid "Simulation has been set"
|
||||
msgstr "Simulation wurde gesended"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:228
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:409
|
||||
msgid "Source"
|
||||
msgstr "Quelle"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:26
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:52
|
||||
msgid "State"
|
||||
msgstr "Status"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:58
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:36
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:67
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:59
|
||||
msgid "State Type"
|
||||
msgstr "Statustyp"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/show.phtml:36
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:68
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:44
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:92
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:261
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:108
|
||||
msgid "Store"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:69
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Form/QuickForm.php:178
|
||||
msgid "Submit"
|
||||
msgstr "Absenden"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:76
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:101
|
||||
msgid "Subprocess only"
|
||||
msgstr "Nur Sub-Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/upload.phtml:8
|
||||
msgid "This has not been implemented yet"
|
||||
msgstr "Das wurde noch nicht implementiert"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:94
|
||||
msgid "Switch to fullscreen mode"
|
||||
msgstr "Zum Vollbildmodus wechseln"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:34
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:18
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:32
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:134
|
||||
msgid "The node type you want to add"
|
||||
msgstr "Der gewünschte Knotentyp"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:35
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:37
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:60
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:35
|
||||
msgid "This is the unique identifier of this process"
|
||||
msgstr "Das ist der eindeutige Identifier dieses Prozesses"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/show.phtml:33
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:257
|
||||
#, php-format
|
||||
msgid "This process has %d pending change(s)."
|
||||
msgstr "Dieser Prozess hat %d ungespeicherte Änderung(en)"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/show.phtml:48
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:276
|
||||
#, php-format
|
||||
msgid "This process shows %d simulated state(s)."
|
||||
msgstr "Dieser Prozess zeigt %d simulierte Zustände"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:39
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:22
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:37
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:28
|
||||
msgid "Tiles"
|
||||
msgstr "Kacheln"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:40
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:42
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:65
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:40
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:70
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:75
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:100
|
||||
msgid "Toplevel Process"
|
||||
msgstr "Toplevel-Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:32
|
||||
msgid "UNKNOWN"
|
||||
msgstr "UNBEKANNT"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:37
|
||||
msgid "Tree"
|
||||
msgstr "Baum"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:88
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:83
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:108
|
||||
msgid "URL pointing to more information about this node"
|
||||
msgstr "URL zu mehr Informationen über diesen Knoten"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/process/show.phtml:10
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:49
|
||||
msgid "Unlock"
|
||||
msgstr "Entsperren"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/ActionBar.php:54
|
||||
msgid "Unlock this process"
|
||||
msgstr "Entsperre diesen Prozess"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:217
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:398
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:111
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:64
|
||||
msgid "Upload"
|
||||
msgstr "Upload"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:35
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/controllers/ProcessController.php:56
|
||||
msgid "Upload a business process config file"
|
||||
msgstr "Lade eine Business-Prozess Konfigurationsdatei hoch"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:64
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:40
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:65
|
||||
msgid "Upload an existing Business Process configuration"
|
||||
msgstr "Lade eine Business-Prozess Konfigurationsdatei hoch"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:74
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:65
|
||||
msgid "Use HARD states"
|
||||
msgstr "HARD-States benutzen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:65
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:41
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:73
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:66
|
||||
msgid "Use SOFT states"
|
||||
msgstr "SOFT-States benutzen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:31
|
||||
msgid "Use current default backend"
|
||||
msgstr "Aktuelles Standard-Backend benutzen"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:124
|
||||
#, php-format
|
||||
msgid "Use current state (%s)"
|
||||
msgstr "Aktuellen Status benutzen (%s)"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:28
|
||||
msgid "Use current state"
|
||||
msgstr "Aktuellen Status benutzen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:53
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:62
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:54
|
||||
msgid "Use the configured default backend"
|
||||
msgstr "Benutze das konfigurierte Standard-Backend"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:39
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:44
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:67
|
||||
msgid ""
|
||||
"Usually this title will be shown for this node. Equals name if not given"
|
||||
msgstr ""
|
||||
"Für gewöhnlich wird dieser Titel für diesen Knoten angezeigt. Entspricht dem "
|
||||
"Namen, wenn nicht angegeben"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:41
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:23
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:42
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:42
|
||||
msgid ""
|
||||
"Usually this title will be shown for this process. Equals name if not given"
|
||||
msgstr ""
|
||||
"Für gewöhnlich wird dieser Titel für diesen Prozess angezeigt. Entspricht "
|
||||
"dem Namen, wenn nicht angegeben"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:63
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:69
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:93
|
||||
msgid "Visualization"
|
||||
msgstr "Darstellung"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/SimulationForm.php:30
|
||||
msgid "WARNING"
|
||||
msgstr "WARNUNG"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/library/Businessprocess/Web/Component/Dashboard.php:42
|
||||
msgid "Welcome to your Business Process Overview"
|
||||
msgstr "Willkommen zur Übersicht deiner Business-Prozesse"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/warnings.phtml:2
|
||||
msgid "Warnings"
|
||||
msgstr "Warnungen"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:66
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/ProcessForm.php:72
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/AddNodeForm.php:96
|
||||
msgid "Where to show this process"
|
||||
msgstr "Wo soll dieser Prozess angezeigt werden"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:61
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/_CreateConfigForm.php:38
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:70
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpUploadForm.php:62
|
||||
msgid "Whether this process should be based on Icinga hard or soft states"
|
||||
msgstr "Ob dieser Prozess auf Icinga's hard- oder soft-states basieren soll"
|
||||
msgstr "Ob dieser Prozess auf Icinga's Hard- oder Softstates basieren soll"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/index/index.phtml:10
|
||||
msgid "existing one"
|
||||
msgstr "einen existierenden"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:82
|
||||
msgid "Whether this process should be linked in the main Icinga Web 2 menu"
|
||||
msgstr "Ob dieser Prozess ins Icinga Web 2 Hauptmenü verlinkt werden soll"
|
||||
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/views/scripts/index/index.phtml:9
|
||||
msgid "new business process"
|
||||
msgstr "neuen Business-Prozess"
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/BpConfigForm.php:85
|
||||
#: /usr/local/icingaweb-modules/businessprocess/application/forms/DeleteNodeForm.php:40
|
||||
msgid "Yes"
|
||||
msgstr "Ja"
|
||||
|
||||
#~ msgid "Show"
|
||||
#~ msgstr "Zeige"
|
||||
#~ msgid ""
|
||||
#~ "As no business process has been defined yet you might want to create a %s "
|
||||
#~ "or upload an %s."
|
||||
#~ msgstr ""
|
||||
#~ "Nachdem noch kein Business-Prozess definiert wurde, möchtest du "
|
||||
#~ "vermutlich einen %s erstellen oder einen %s hochladen."
|
||||
|
||||
#~ msgid "CRITICAL"
|
||||
#~ msgstr "KRITISCH"
|
||||
|
||||
#~ msgid "Configure your first business process"
|
||||
#~ msgstr "Konfiguriere deinen ersten Business-Prozess"
|
||||
|
||||
#~ msgid "OK"
|
||||
#~ msgstr "OK"
|
||||
|
||||
#~ msgid "PENDING"
|
||||
#~ msgstr "PENDING"
|
||||
|
||||
#~ msgid "Parser waring on %s:%s: %s"
|
||||
#~ msgstr "Parse-Warnung an %s:%s: %s"
|
||||
|
||||
#~ msgid "Plugin output"
|
||||
#~ msgstr "Plugin-Ausgabe"
|
||||
|
||||
#~ msgid "Reporting"
|
||||
#~ msgstr "Reporting"
|
||||
|
||||
#~ msgid "This has not been implemented yet"
|
||||
#~ msgstr "Das wurde noch nicht implementiert"
|
||||
|
||||
#~ msgid "UNKNOWN"
|
||||
#~ msgstr "UNBEKANNT"
|
||||
|
||||
#~ msgid "Use current default backend"
|
||||
#~ msgstr "Aktuelles Standard-Backend benutzen"
|
||||
|
||||
#~ msgid "WARNING"
|
||||
#~ msgstr "WARNUNG"
|
||||
|
||||
#~ msgid "Warnings"
|
||||
#~ msgstr "Warnungen"
|
||||
|
||||
#~ msgid "min"
|
||||
#~ msgstr "min"
|
||||
|
|
|
|||
15
application/views/helpers/FormSimpleNote.php
Normal file
15
application/views/helpers/FormSimpleNote.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
// Avoid complaints about missing namespace and invalid class name
|
||||
// @codingStandardsIgnoreStart
|
||||
class Zend_View_Helper_FormSimpleNote extends Zend_View_Helper_FormElement
|
||||
{
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
public function formSimpleNote($name, $value = null)
|
||||
{
|
||||
$info = $this->_getInfo($name, $value);
|
||||
extract($info); // name, value, attribs, options, listsep, disable
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,24 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @codingStandardsIgnoreStart
|
||||
*/
|
||||
class Zend_View_Helper_RenderStateBadges extends Zend_View_Helper_Abstract
|
||||
{
|
||||
// @codingStandardsIgnoreEnd
|
||||
public function renderStateBadges($summary)
|
||||
{
|
||||
$html = '';
|
||||
|
||||
foreach ($summary as $state => $cnt) {
|
||||
if ($cnt === 0) continue;
|
||||
if ($state === 'OK') continue;
|
||||
if ($state === 'UP') continue;
|
||||
if ($cnt === 0
|
||||
|| $state === 'OK'
|
||||
|| $state === 'UP'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$html .= '<span class="badge badge-' . strtolower($state)
|
||||
. '" title="' . mt('monitoring', $state) . '">'
|
||||
. $cnt . '</span>';
|
||||
|
|
|
|||
2
application/views/scripts/default.phtml
Normal file
2
application/views/scripts/default.phtml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?= $this->controls->render() ?>
|
||||
<?= $this->content->render() ?>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<?php if ($this->bp->isEditMode()): ?>
|
||||
<?php if ($this->bp->hasBeenChanged()): ?>
|
||||
<a href="<?= $this->url()->without('edit') ?>" title="<?= $this->escape('Store modifications') ?>"><?= $this->icon('ok') ?></a>
|
||||
<?php endif ?>
|
||||
<a href="<?= $this->url()->without('edit') ?>" title="<?= $this->escape('Dismiss modifications') ?>"><?= $this->icon('cancel') ?></a>
|
||||
<?php else: ?>
|
||||
<a href="<?= $this->url()->with('edit', true) ?>" title="<?= $this->escape('Modify this process') ?>"><?= $this->icon('wrench') ?></a>
|
||||
<?php endif ?>
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h1><?= $this->translate('Configure your first business process') ?></h1>
|
||||
<p><?= sprintf (
|
||||
$this->translate('As no business process has been defined yet you might want to create a %s or upload an %s.'),
|
||||
$this->qlink($this->translate('new business process'), 'businessprocess/process/create'),
|
||||
$this->qlink($this->translate('existing one'), 'businessprocess/process/upload')
|
||||
) ?></p>
|
||||
</div>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Module\Businessprocess\HostNode;
|
||||
use Icinga\Module\Businessprocess\ServiceNode;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
|
||||
?><div class="content">
|
||||
<h1><?= $this->translate('Add new process node') ?></h1>
|
||||
<?= $this->form ?>
|
||||
</div>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Module\Businessprocess\HostNode;
|
||||
use Icinga\Module\Businessprocess\ServiceNode;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
|
||||
?><div class="content">
|
||||
<h1><?= $this->escape(
|
||||
sprintf(
|
||||
$this->translate('Modify process node: %s'),
|
||||
$node
|
||||
)
|
||||
) ?></h1>
|
||||
<?= $this->form ?>
|
||||
</div>
|
||||
|
|
@ -1 +0,0 @@
|
|||
__CLOSEME__
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<!--<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
</div>-->
|
||||
|
||||
<div class="content">
|
||||
<h1>BI Simulation: <?= $this->escape(preg_replace('/;/', ' - ', $this->node)) ?></h1>
|
||||
<?= $this->form ?>
|
||||
</div>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<h1><?= $this->escape($this->title) ?>
|
||||
<a href="<?= $this->url('businessprocess/process/source', array(
|
||||
'config' => $this->configName
|
||||
)) ?>" title="<?= $this->escape('Show configuration source') ?>"><?= $this->icon('doc-text') ?></a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<?= $this->form ?>
|
||||
<div data-base-target="_main">
|
||||
<?= $this->deleteForm ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<h1><?= $this->escape($this->title) ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<?= $this->form ?>
|
||||
</div>
|
||||
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
<?php
|
||||
$months = array(
|
||||
'Jänner',
|
||||
'Februar',
|
||||
'März',
|
||||
'April',
|
||||
'Mai',
|
||||
'Juni',
|
||||
'Juli',
|
||||
'August',
|
||||
'September',
|
||||
'Oktober',
|
||||
'November',
|
||||
'Dezember',
|
||||
);
|
||||
?><table style="width: 100%;">
|
||||
<tr>
|
||||
<th style="width: 10%;"> </th>
|
||||
<? for ($i = 1; $i <= 12; $i++): ?>
|
||||
<th style="width: 7.5%; border: 1px solid black;"><?= $months[$i - 1] ?></th>
|
||||
<? endfor ?>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div style="overflow: auto">
|
||||
<table>
|
||||
<tr>
|
||||
<? for ($i = 1; $i <= 12; $i++): ?>
|
||||
<td style="border-right: 1px solid black;"><div style="width: 600px; height: 1px; overflow: hidden;"> </div><?= $months[$i - 1] ?></td>
|
||||
<? endfor ?>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="overflow: auto; ">
|
||||
<?php
|
||||
|
||||
function stateColor($state)
|
||||
{
|
||||
switch($state) {
|
||||
case 0:
|
||||
$color = '#0f0';
|
||||
break;
|
||||
case 1:
|
||||
$color = 'orange';
|
||||
break;
|
||||
case 2:
|
||||
$color = '#f00';
|
||||
break;
|
||||
default: // und case 3
|
||||
$color = '#ccc';
|
||||
}
|
||||
return $color;
|
||||
}
|
||||
|
||||
$next_color = null;
|
||||
$color = null;
|
||||
|
||||
$start = mktime(0, 0, 0, 0, 0, (int) date('Y'));
|
||||
$current_offset = $start;
|
||||
$htm = '';
|
||||
$cnt = 0;
|
||||
$last_host = null;
|
||||
$last_service = null;
|
||||
foreach ($this->history as $entry) {
|
||||
if ($entry->hostname !== $last_host || $entry->service !== $last_service) {
|
||||
|
||||
echo '<span style="clear: both;" />' . "\n";
|
||||
}
|
||||
$cnt++;
|
||||
if ($cnt > 10000) break;
|
||||
$duration = $entry->timestamp - $current_offset;
|
||||
if ($next_color === null) {
|
||||
$color = stateColor($entry->last_state);
|
||||
} else {
|
||||
$color = $next_color;
|
||||
}
|
||||
$next_color = stateColor($entry->state);
|
||||
|
||||
if ($entry->state == 0) {
|
||||
$offset = ceil($duration / 3600 / 6);
|
||||
} else {
|
||||
$offset = floor($duration / 3600 / 6);
|
||||
}
|
||||
echo '<div style="overflow: hidden; height: 10px; float: left; width: ' . $offset . 'px; background-color:' . $color . ';"> </div>';
|
||||
$current_offset += $duration;
|
||||
|
||||
$last_host = $entry->hostname;
|
||||
$last_service = $entry->service;
|
||||
|
||||
}
|
||||
|
||||
|
||||
?></div>
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
|
||||
?>
|
||||
<?php if (! $this->compact): ?>
|
||||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<h1><form method="post" action="<?= $this->url()->without('node')->without('unlocked') ?>">
|
||||
<?= $this->formSelect('config', $this->configName, array('class' => 'autosubmit'), $this->processList) ?>
|
||||
</form>
|
||||
|
||||
<a href="<?= $this->url()->with('mode', 'toplevel')->without('unlocked') ?>" title="<?= $this->escape('Switch to toplevel view') ?>"><?= $this->icon('dashboard') ?></a>
|
||||
<?php if ($this->bpconfig->isLocked()): ?>
|
||||
<a href="<?= $this->url()->with('unlocked', true) ?>" title="<?= $this->escape($this->translate('Unlock this process')) ?>"><?= $this->icon('lock') ?></a>
|
||||
<?php else: ?>
|
||||
<?php if (! $this->bpconfig->isEmpty()): ?>
|
||||
<a href="<?= $this->url()->without('unlocked') ?>" style="color: red" title="<?= $this->escape($this->translate('Lock this process')) ?>"><?= $this->icon('lock-open') ?></a>
|
||||
<?php endif ?>
|
||||
<a href="<?= $this->url('businessprocess/process/config', array('config' => $this->configName)) ?>" title="<?= $this->escape('Modify this process') ?>" data-base-target="_next"><?= $this->icon('wrench') ?></a>
|
||||
<?php endif ?>
|
||||
<a href="<?= $this->url('businessprocess/process/create') ?>" title="<?= $this->escape('Create a new business process configuration') ?>"><?= $this->icon('plus') ?></a>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="content<?= $this->compact ? ' compact' : '' ?>" data-base-target="_next">
|
||||
<?php if (! $this->bpconfig->isLocked()): ?>
|
||||
<?= $this->qlink('Add new node', 'businessprocess/node/add', array('config' => $this->configName)) ?>
|
||||
<?php endif ?>
|
||||
<?php if ($this->bpconfig->hasErrors() || $this->bpconfig->hasChanges() || $this->bpconfig->hasSimulations()): ?>
|
||||
<ul class="error">
|
||||
<?php foreach ($this->bpconfig->getErrors() as $error): ?>
|
||||
<li><?= $this->escape($error) ?></li>
|
||||
<?php endforeach ?>
|
||||
<?php if ($this->bpconfig->hasChanges()): ?>
|
||||
<li><?= sprintf(
|
||||
$this->translate('This process has %d pending change(s).'),
|
||||
$this->bpconfig->countChanges()
|
||||
) ?> <?= $this->qlink(
|
||||
$this->translate('Store'),
|
||||
'businessprocess/process/config',
|
||||
array('config' => $this->configName)
|
||||
) ?> <?= $this->qlink(
|
||||
$this->translate('Dismiss'),
|
||||
$this->url()->with('dismissChanges', true),
|
||||
null
|
||||
) ?></li>
|
||||
<?php endif ?>
|
||||
<?php if ($this->bpconfig->hasSimulations()): ?>
|
||||
<li><?= sprintf(
|
||||
$this->translate('This process shows %d simulated state(s).'),
|
||||
$this->bpconfig->countSimulations()
|
||||
) ?> <?= $this->qlink(
|
||||
$this->translate('Dismiss'),
|
||||
$this->url()->with('dismissSimulations', true),
|
||||
null
|
||||
) ?></li>
|
||||
<?php endif ?>
|
||||
</ul>
|
||||
<?php endif ?>
|
||||
<div class="bp">
|
||||
<?= $this->bp->renderHtml($this) ?>
|
||||
<?php if (! $this->bpconfig->isLocked()): ?>
|
||||
<?php if ($this->bp instanceof BusinessProcess): /* do not render when showing subtree */ ?>
|
||||
<?= $this->bp->renderUnbound($this) ?>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?= $this->render('warnings.phtml') ?>
|
||||
</div>
|
||||
|
|
@ -1,21 +1,9 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<h1><?= $this->escape($this->title) ?>
|
||||
<a href="<?= $this->url('businessprocess/process/download', array(
|
||||
'config' => $this->configName
|
||||
)) ?>" target="_self" title="<?= $this->escape($this->translate('Download process configuration')) ?>"><?= $this->icon('download') ?></a>
|
||||
<?php if ($this->showDiff): ?>
|
||||
<a href="<?= $this->url()->without('showDiff') ?>" title="<?= $this->escape($this->translate('Show source code')) ?>"><?= $this->icon('doc-text') ?></a>
|
||||
<?php else: ?>
|
||||
<a href="<?= $this->url()->with('showDiff', true) ?>" title="<?= $this->escape($this->translate('Highlight changes')) ?>"><?= $this->icon('flapping') ?></a>
|
||||
<?php endif ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?= $this->controls->render() ?>
|
||||
|
||||
<div class="content">
|
||||
<?php if ($this->showDiff): ?>
|
||||
<div class="diff">
|
||||
<?= $this->diff->renderHtml() ?>
|
||||
<?= $this->diff->render() ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<table class="sourcecode">
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Module\Businessprocess\ImportedNode;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
|
||||
$count = $this->bp->countChildren();
|
||||
$howMany = 'normal';
|
||||
|
||||
if ($count < 20) {
|
||||
$howMany = 'few';
|
||||
} elseif ($count > 50) {
|
||||
$howMany = 'many';
|
||||
}
|
||||
|
||||
?>
|
||||
<?php if (! $this->compact): ?>
|
||||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<h1><form method="post" action="<?= $this->url()->without('node')->without('unlocked') ?>">
|
||||
<?= $this->formSelect('config', $this->configName, array('class' => 'autosubmit'), $this->processList) ?>
|
||||
</form>
|
||||
<a href="<?= $this->url()->without('mode') ?>" title="<?= $this->escape('Switch to tree view') ?>" style="float: right"><?= $this->icon('sitemap') ?></a>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="content<?= $this->compact ? ' compact' : '' ?>" data-base-target="_next">
|
||||
<div class="toplevel <?= $howMany ?>" data-base-target="_next">
|
||||
<?php foreach ($this->bp->getChildren() as $name => $node): ?>
|
||||
<div class="<?= strtolower($node->getStateName()) ?><?= $node->isHandled() ? ' handled' : '' ?>">
|
||||
<?php if ($node instanceof ImportedNode): ?>
|
||||
<a href="<?= $this->url('businessprocess/process/show', array('config' => $node->getConfigName(), 'node' => $name)) ?>">
|
||||
<?php else: ?>
|
||||
<a href="<?= $this->url('businessprocess/process/show', array('config' => $this->configName, 'node' => $name)) ?>">
|
||||
<?php endif ?>
|
||||
<?= $this->escape($node->getAlias()) ?><?php
|
||||
|
||||
if ($node instanceof BpNode) {
|
||||
echo $this->renderStateBadges($node->getStateSummary());
|
||||
}
|
||||
|
||||
?></a>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?= $this->render('warnings.phtml') ?>
|
||||
</div>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<h1><?= $this->escape($this->title) ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<ul class="error">
|
||||
<li><?= $this->translate('This has not been implemented yet') ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<?php if ($this->bp->isSimulationMode()): ?>
|
||||
<a href="<?= $this->url()->without('simulation') ?>" title="<?= $this->escape('Switch to live mode') ?>"><?= $this->icon('globe') ?></a>
|
||||
<?php else: ?>
|
||||
<a href="<?= $this->url()->with('simulation', true) ?>" title="<?= $this->escape('Switch to simulation mode') ?>"><?= $this->icon('magic') ?></a>
|
||||
<?php endif ?>
|
||||
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<?php if ($this->warnings): ?>
|
||||
<h2><?= $this->translate('Warnings') ?></h2>
|
||||
<?php foreach ($this->warnings as $warning): ?>
|
||||
<?= $this->escape($warning) ?><br />
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
|
|
@ -1,7 +1,56 @@
|
|||
<?php
|
||||
|
||||
$section = $this->menuSection(N_('Overview'))
|
||||
->add($this->translate('Business Processes'))
|
||||
->setPriority(45)
|
||||
->setUrl('businessprocess');
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
|
||||
/** @var \Icinga\Application\Modules\Module $this */
|
||||
$section = $this->menuSection(N_('Business Processes'), array(
|
||||
'url' => 'businessprocess',
|
||||
'icon' => 'sitemap',
|
||||
'priority' => 46
|
||||
));
|
||||
|
||||
try {
|
||||
$storage = new LegacyStorage(
|
||||
$this->getConfig()->getSection('global')
|
||||
);
|
||||
|
||||
$prio = 0;
|
||||
foreach ($storage->listProcessNames() as $name) {
|
||||
$prio++;
|
||||
|
||||
$meta = $storage->loadMetadata($name);
|
||||
if ($meta->get('AddToMenu') === 'no') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($prio > 5) {
|
||||
$section->add(N_('Show all'), array(
|
||||
'url' => 'businessprocess',
|
||||
'priority' => $prio
|
||||
));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$section->add($meta->getTitle(), array(
|
||||
'url' => 'businessprocess/process/show',
|
||||
'urlParameters' => array('config' => $name),
|
||||
'priority' => $prio
|
||||
));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Well... there is not much we could do here
|
||||
}
|
||||
|
||||
$this->providePermission(
|
||||
'businessprocess/showall',
|
||||
$this->translate('Allow to see all available processes, regardless of configured restrictions')
|
||||
);
|
||||
$this->providePermission(
|
||||
'businessprocess/create',
|
||||
$this->translate('Allow to create whole new process configuration (files)')
|
||||
);
|
||||
$this->providePermission(
|
||||
'businessprocess/modify',
|
||||
$this->translate('Allow to modify process definitions, to add and remove nodes')
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Application\Benchmark;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Module\Businessprocess\Exception\NestingError;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Exception;
|
||||
|
||||
class BusinessProcess
|
||||
class BpConfig
|
||||
{
|
||||
const SOFT_STATE = 0;
|
||||
|
||||
|
|
@ -27,6 +29,9 @@ class BusinessProcess
|
|||
*/
|
||||
protected $backend;
|
||||
|
||||
/** @var Metadata */
|
||||
protected $metadata;
|
||||
|
||||
/**
|
||||
* Business process name
|
||||
*
|
||||
|
|
@ -76,13 +81,6 @@ class BusinessProcess
|
|||
*/
|
||||
protected $root_nodes = array();
|
||||
|
||||
/**
|
||||
* All check names { 'hostA;ping' => true, ... }
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $all_checks = array();
|
||||
|
||||
/**
|
||||
* All host names { 'hostA' => true, ... }
|
||||
*
|
||||
|
|
@ -90,6 +88,11 @@ class BusinessProcess
|
|||
*/
|
||||
protected $hosts = array();
|
||||
|
||||
/** @var bool Whether catchable errors should be thrown nonetheless */
|
||||
protected $throwErrors = false;
|
||||
|
||||
protected $loopDetection = array();
|
||||
|
||||
/**
|
||||
* Applied state simulation
|
||||
*
|
||||
|
|
@ -97,25 +100,51 @@ class BusinessProcess
|
|||
*/
|
||||
protected $simulation;
|
||||
|
||||
/**
|
||||
* Whether we are in edit mode
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $editMode = false;
|
||||
|
||||
protected $locked = true;
|
||||
|
||||
protected $changeCount = 0;
|
||||
|
||||
protected $simulationCount = 0;
|
||||
|
||||
/** @var ProcessChanges */
|
||||
protected $appliedChanges;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve metadata for this configuration
|
||||
*
|
||||
* @return Metadata
|
||||
*/
|
||||
public function getMetadata()
|
||||
{
|
||||
if ($this->metadata === null) {
|
||||
$this->metadata = new Metadata($this->name);
|
||||
}
|
||||
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set metadata
|
||||
*
|
||||
* @param Metadata $metadata
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMetadata(Metadata $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply pending process changes
|
||||
*
|
||||
* @param ProcessChanges $changes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function applyChanges(ProcessChanges $changes)
|
||||
{
|
||||
$cnt = 0;
|
||||
|
|
@ -130,6 +159,13 @@ class BusinessProcess
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a state simulation
|
||||
*
|
||||
* @param Simulation $simulation
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function applySimulation(Simulation $simulation)
|
||||
{
|
||||
$cnt = 0;
|
||||
|
|
@ -147,28 +183,57 @@ class BusinessProcess
|
|||
}
|
||||
|
||||
$this->simulationCount = $cnt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of applied changes
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countChanges()
|
||||
{
|
||||
return $this->changeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether changes have been applied to this configuration
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function hasChanges()
|
||||
{
|
||||
return $this->countChanges() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHtmlId()
|
||||
{
|
||||
return 'businessprocess-' . preg_replace('/[\r\n\t\s]/', '_', $this->getName());
|
||||
}
|
||||
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
|
|
@ -177,28 +242,22 @@ class BusinessProcess
|
|||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title ?: $this->getName();
|
||||
return $this->getMetadata()->getTitle();
|
||||
}
|
||||
|
||||
public function hasTitle()
|
||||
{
|
||||
return $this->title !== null;
|
||||
}
|
||||
|
||||
public function setBackendName($name)
|
||||
{
|
||||
$this->backendName = $name;
|
||||
return $this;
|
||||
return $this->getMetadata()->has('Title');
|
||||
}
|
||||
|
||||
public function getBackendName()
|
||||
{
|
||||
return $this->backendName;
|
||||
return $this->getMetadata()->get('Backend');
|
||||
}
|
||||
|
||||
public function hasBackendName()
|
||||
{
|
||||
return $this->backendName !== null;
|
||||
return $this->getMetadata()->has('Backend');
|
||||
}
|
||||
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
|
|
@ -210,7 +269,7 @@ class BusinessProcess
|
|||
public function getBackend()
|
||||
{
|
||||
if ($this->backend === null) {
|
||||
$this->backend = MonitoringBackend::createBackend(
|
||||
$this->backend = MonitoringBackend::instance(
|
||||
$this->getBackendName()
|
||||
);
|
||||
}
|
||||
|
|
@ -228,22 +287,6 @@ class BusinessProcess
|
|||
return false;
|
||||
}
|
||||
|
||||
public function isLocked()
|
||||
{
|
||||
return $this->locked;
|
||||
}
|
||||
|
||||
public function lock($lock = true)
|
||||
{
|
||||
$this->locked = (bool) $lock;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unlock()
|
||||
{
|
||||
return $this->lock(false);
|
||||
}
|
||||
|
||||
public function hasSimulations()
|
||||
{
|
||||
return $this->countSimulations() > 0;
|
||||
|
|
@ -254,17 +297,6 @@ class BusinessProcess
|
|||
return $this->simulationCount;
|
||||
}
|
||||
|
||||
public function setEditMode($mode = true)
|
||||
{
|
||||
$this->editMode = (bool) $mode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isEditMode()
|
||||
{
|
||||
return $this->editMode;
|
||||
}
|
||||
|
||||
public function clearAppliedChanges()
|
||||
{
|
||||
if ($this->appliedChanges !== null) {
|
||||
|
|
@ -292,7 +324,7 @@ class BusinessProcess
|
|||
|
||||
public function usesHardStates()
|
||||
{
|
||||
$this->state_type === self::HARD_STATE;
|
||||
return $this->state_type === self::HARD_STATE;
|
||||
}
|
||||
|
||||
public function addRootNode($name)
|
||||
|
|
@ -315,122 +347,38 @@ class BusinessProcess
|
|||
return array_key_exists($name, $this->root_nodes);
|
||||
}
|
||||
|
||||
public function retrieveStatesFromBackend()
|
||||
{
|
||||
try {
|
||||
$this->reallyRetrieveStatesFromBackend();
|
||||
} catch (Exception $e) {
|
||||
$this->error(
|
||||
$this->translate('Could not retrieve process state: %s'),
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function reallyRetrieveStatesFromBackend()
|
||||
{
|
||||
Benchmark::measure('Retrieving states for business process ' . $this->getName());
|
||||
$backend = $this->getBackend();
|
||||
// TODO: Split apart, create a dedicated function.
|
||||
// Separate "parse-logic" from "retrieve-state-logic"
|
||||
// Allow DB-based backend
|
||||
// Use IcingaWeb2 Multi-Backend-Support
|
||||
$check_results = array();
|
||||
$hostFilter = array_keys($this->hosts);
|
||||
|
||||
if ($this->state_type === self::HARD_STATE) {
|
||||
$hostStateColumn = 'host_hard_state';
|
||||
$hostStateChangeColumn = 'host_last_hard_state_change';
|
||||
$serviceStateColumn = 'service_hard_state';
|
||||
$serviceStateChangeColumn = 'service_last_hard_state_change';
|
||||
} else {
|
||||
$hostStateColumn = 'host_state';
|
||||
$hostStateChangeColumn = 'host_last_state_change';
|
||||
$serviceStateColumn = 'service_state';
|
||||
$serviceStateChangeColumn = 'service_last_state_change';
|
||||
}
|
||||
$filter = Filter::matchAny();
|
||||
foreach ($hostFilter as $host) {
|
||||
$filter->addFilter(Filter::where('host_name', $host));
|
||||
}
|
||||
|
||||
if ($filter->isEmpty()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$hostStatus = $backend->select()->from('hostStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'last_state_change' => $hostStateChangeColumn,
|
||||
'in_downtime' => 'host_in_downtime',
|
||||
'ack' => 'host_acknowledged',
|
||||
'state' => $hostStateColumn
|
||||
))->applyFilter($filter)->getQuery()->fetchAll();
|
||||
|
||||
$serviceStatus = $backend->select()->from('serviceStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'service' => 'service_description',
|
||||
'last_state_change' => $serviceStateChangeColumn,
|
||||
'in_downtime' => 'service_in_downtime',
|
||||
'ack' => 'service_acknowledged',
|
||||
'state' => $serviceStateColumn
|
||||
))->applyFilter($filter)->getQuery()->fetchAll();
|
||||
|
||||
foreach ($serviceStatus as $row) {
|
||||
$this->handleDbRow($row);
|
||||
}
|
||||
|
||||
foreach ($hostStatus as $row) {
|
||||
$this->handleDbRow($row);
|
||||
}
|
||||
|
||||
ksort($this->root_nodes);
|
||||
Benchmark::measure('Got states for business process ' . $this->getName());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function handleDbRow($row)
|
||||
{
|
||||
$key = $row->hostname;
|
||||
if (property_exists($row, 'service')) {
|
||||
$key .= ';' . $row->service;
|
||||
} else {
|
||||
$key .= ';Hoststatus';
|
||||
}
|
||||
// We fetch more states than we need, so skip unknown ones
|
||||
if (! $this->hasNode($key)) return;
|
||||
$node = $this->getNode($key);
|
||||
|
||||
if ($row->state !== null) {
|
||||
$node->setState($row->state)->setMissing(false);
|
||||
}
|
||||
if ($row->last_state_change !== null) {
|
||||
$node->setLastStateChange($row->last_state_change);
|
||||
}
|
||||
if ((int) $row->in_downtime === 1) {
|
||||
$node->setDowntime(true);
|
||||
}
|
||||
if ((int) $row->ack === 1) {
|
||||
$node->setAck(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->getRootNodes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function countChildren()
|
||||
{
|
||||
return count($this->root_nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getRootNodes()
|
||||
{
|
||||
ksort($this->root_nodes);
|
||||
return $this->root_nodes;
|
||||
}
|
||||
|
||||
public function listRootNodes()
|
||||
{
|
||||
$names = array_keys($this->root_nodes);
|
||||
sort($names);
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function getNodes()
|
||||
{
|
||||
return $this->nodes;
|
||||
|
|
@ -441,6 +389,11 @@ class BusinessProcess
|
|||
return array_key_exists($name, $this->nodes);
|
||||
}
|
||||
|
||||
public function hasRootNode($name)
|
||||
{
|
||||
return array_key_exists($name, $this->root_nodes);
|
||||
}
|
||||
|
||||
public function createService($host, $service)
|
||||
{
|
||||
$node = new ServiceNode(
|
||||
|
|
@ -463,13 +416,53 @@ class BusinessProcess
|
|||
return $node;
|
||||
}
|
||||
|
||||
public function createImportedNode($config, $name)
|
||||
public function listInvolvedHostNames()
|
||||
{
|
||||
$node = new ImportedNode($this, (object) array('name' => $name, 'configName' => $config));
|
||||
$this->nodes[$name] = $node;
|
||||
return array_keys($this->hosts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and attach a new process (BpNode)
|
||||
*
|
||||
* @param string $name Process name
|
||||
* @param string $operator Operator (defaults to &)
|
||||
*
|
||||
* @return BpNode
|
||||
*/
|
||||
public function createBp($name, $operator = '&')
|
||||
{
|
||||
$node = new BpNode($this, (object) array(
|
||||
'name' => $name,
|
||||
'operator' => $operator,
|
||||
'child_names' => array(),
|
||||
));
|
||||
|
||||
$this->addNode($name, $node);
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function createMissingBp($name)
|
||||
{
|
||||
return $this->createBp($name)->setMissing();
|
||||
}
|
||||
|
||||
public function createImportedNode($config, $name = null)
|
||||
{
|
||||
$params = (object) array('configName' => $config);
|
||||
if ($name !== null) {
|
||||
$params->node = $name;
|
||||
}
|
||||
|
||||
$node = new ImportedNode($this, $params);
|
||||
$this->nodes[$node->getName()] = $node;
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return Node
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getNode($name)
|
||||
{
|
||||
if (array_key_exists($name, $this->nodes)) {
|
||||
|
|
@ -482,7 +475,12 @@ class BusinessProcess
|
|||
if ($pos !== false) {
|
||||
$host = substr($name, 0, $pos);
|
||||
$service = substr($name, $pos + 1);
|
||||
return $this->createService($host, $service);
|
||||
// TODO: deactivated, this scares me, test it
|
||||
if ($service === 'Hoststatus') {
|
||||
return $this->createHost($host);
|
||||
} else {
|
||||
return $this->createService($host, $service);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception(
|
||||
|
|
@ -490,13 +488,55 @@ class BusinessProcess
|
|||
);
|
||||
}
|
||||
|
||||
public function addObjectName($name)
|
||||
/**
|
||||
* @param $name
|
||||
* @return BpNode
|
||||
*
|
||||
* @throws NotFoundError
|
||||
*/
|
||||
public function getBpNode($name)
|
||||
{
|
||||
$this->all_checks[$name] = 1;
|
||||
if ($this->hasBpNode($name)) {
|
||||
return $this->nodes[$name];
|
||||
} else {
|
||||
throw new NotFoundError('Trying to access a missing business process node "%s"', $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBpNode($name)
|
||||
{
|
||||
return array_key_exists($name, $this->nodes)
|
||||
&& $this->nodes[$name] instanceof BpNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state for a specific node
|
||||
*
|
||||
* @param string $name Node name
|
||||
* @param int $state Desired state
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setNodeState($name, $state)
|
||||
{
|
||||
$this->getNode($name)->setState($state);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addNode($name, Node $node)
|
||||
/**
|
||||
* Add the given node to the given BpNode
|
||||
*
|
||||
* @param $name
|
||||
* @param BpNode $node
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addNode($name, BpNode $node)
|
||||
{
|
||||
if (array_key_exists($name, $this->nodes)) {
|
||||
$this->warn(
|
||||
|
|
@ -523,16 +563,53 @@ class BusinessProcess
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function listBpNodes()
|
||||
/**
|
||||
* Remove all occurrences of a specific node by name
|
||||
*
|
||||
* @param $name
|
||||
*/
|
||||
public function removeNode($name)
|
||||
{
|
||||
unset($this->nodes[$name]);
|
||||
if (array_key_exists($name, $this->root_nodes)) {
|
||||
unset($this->root_nodes[$name]);
|
||||
}
|
||||
|
||||
foreach ($this->getBpNodes() as $node) {
|
||||
if ($node->hasChild($name)) {
|
||||
$node->removeChild($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all business process nodes
|
||||
*
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getBpNodes()
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
foreach ($this->nodes as $node) {
|
||||
if (! $node instanceof BpNode) {
|
||||
continue;
|
||||
if ($node instanceof BpNode) {
|
||||
$nodes[$node->getName()] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
$name = (string) $node;
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all business process node names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listBpNodes()
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
foreach ($this->getBpNodes() as $name => $node) {
|
||||
$alias = $node->getAlias();
|
||||
$nodes[$name] = $name === $alias ? $name : sprintf('%s (%s)', $alias, $node);
|
||||
}
|
||||
|
|
@ -541,42 +618,57 @@ class BusinessProcess
|
|||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* All business process nodes defined in this config but not
|
||||
* assigned to any parent
|
||||
*
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getUnboundNodes()
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
foreach ($this->nodes as $node) {
|
||||
if (! $node instanceof BpNode) {
|
||||
continue;
|
||||
}
|
||||
foreach ($this->getBpNodes() as $name => $node) {
|
||||
|
||||
if ($node->hasParents()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node->getDisplay() === 0) {
|
||||
$nodes[(string) $node] = $node;
|
||||
$nodes[$name] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasWarnings()
|
||||
{
|
||||
return ! empty($this->warnings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getWarnings()
|
||||
{
|
||||
return $this->warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasErrors()
|
||||
{
|
||||
return ! empty($this->errors) || $this->isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
$errors = $this->errors;
|
||||
|
|
@ -591,104 +683,103 @@ class BusinessProcess
|
|||
return $errors;
|
||||
}
|
||||
|
||||
protected function translate($msg)
|
||||
/**
|
||||
* Translation helper
|
||||
*
|
||||
* @param $msg
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function translate($msg)
|
||||
{
|
||||
return mt('businessprocess', $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to our warning stack
|
||||
*
|
||||
* @param $msg
|
||||
*/
|
||||
protected function warn($msg)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
if (isset($this->parsing_line_number)) {
|
||||
$this->warnings[] = sprintf(
|
||||
$this->translate('Parser waring on %s:%s: %s'),
|
||||
$this->filename,
|
||||
$this->parsing_line_number,
|
||||
vsprintf($msg, $args)
|
||||
);
|
||||
} else {
|
||||
$this->warnings[] = vsprintf($msg, $args);
|
||||
}
|
||||
$this->warnings[] = vsprintf($msg, $args);
|
||||
}
|
||||
|
||||
protected function error($msg)
|
||||
/**
|
||||
* @param string $msg,...
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws IcingaException
|
||||
*/
|
||||
public function addError($msg)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$this->errors[] = vsprintf($msg, $args);
|
||||
$msg = vsprintf($msg, $args);
|
||||
if ($this->throwErrors) {
|
||||
throw new IcingaException($msg);
|
||||
}
|
||||
|
||||
$this->errors[] = $msg;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toLegacyConfigString()
|
||||
/**
|
||||
* Decide whether errors should be thrown or collected
|
||||
*
|
||||
* @param bool $throw
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function throwErrors($throw = true)
|
||||
{
|
||||
$settings = array();
|
||||
if ($this->hasTitle()) {
|
||||
$settings['Title'] = $this->getTitle();
|
||||
}
|
||||
// TODO: backendName?
|
||||
if ($this->backend) {
|
||||
$settings['Backend'] = $this->backend->getName();
|
||||
}
|
||||
$settings['Statetype'] = $this->usesSoftStates() ? 'soft' : 'hard';
|
||||
|
||||
if (false) {
|
||||
$settings['SLA Hosts'] = implode(', ', array());
|
||||
}
|
||||
|
||||
$conf = "### Business Process Config File ###\n#\n";
|
||||
foreach ($settings as $key => $value) {
|
||||
$conf .= sprintf("# %-9s : %s\n", $key, $value);
|
||||
}
|
||||
|
||||
$conf .= "#\n###################################\n\n";
|
||||
|
||||
$rendered = array();
|
||||
foreach ($this->getChildren() as $child) {
|
||||
$conf .= $child->toLegacyConfigString($rendered);
|
||||
$rendered[(string) $child] = true;
|
||||
}
|
||||
foreach ($this->getUnboundNodes() as $node) {
|
||||
$conf .= $node->toLegacyConfigString($rendered);
|
||||
$rendered[(string) $node] = true;
|
||||
}
|
||||
return $conf . "\n";
|
||||
$this->throwErrors = $throw;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin loop detection for the given name
|
||||
*
|
||||
* Will throw a NestingError in case this node will be met again below itself
|
||||
*
|
||||
* @param $name
|
||||
*
|
||||
* @throws NestingError
|
||||
*/
|
||||
public function beginLoopDetection($name)
|
||||
{
|
||||
// echo "Begin loop $name\n";
|
||||
if (array_key_exists($name, $this->loopDetection)) {
|
||||
$loop = array_keys($this->loopDetection);
|
||||
$loop[] = $name;
|
||||
$this->loopDetection = array();
|
||||
throw new NestingError('Loop detected: %s', implode(' -> ', $loop));
|
||||
}
|
||||
|
||||
$this->loopDetection[$name] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given name from the loop detection stack
|
||||
*
|
||||
* @param $name
|
||||
*/
|
||||
public function endLoopDetection($name)
|
||||
{
|
||||
// echo "End loop $this->name\n";
|
||||
unset($this->loopDetection[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this configuration has any Nodes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->countChildren() === 0;
|
||||
}
|
||||
|
||||
public function renderHtml($view)
|
||||
{
|
||||
$html = '';
|
||||
foreach ($this->getRootNodes() as $name => $node) {
|
||||
$html .= $node->renderHtml($view);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function renderUnbound($view)
|
||||
{
|
||||
$html = '';
|
||||
|
||||
$unbound = $this->getUnboundNodes();
|
||||
if (empty($unbound)) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$parent = new BpNode($this, (object) array(
|
||||
'name' => '__unbound__',
|
||||
'operator' => '|',
|
||||
'child_names' => array_keys($unbound)
|
||||
));
|
||||
$parent->getState();
|
||||
$parent->setMissing()
|
||||
->setDowntime(false)
|
||||
->setAck(false)
|
||||
->setAlias('Unbound nodes');
|
||||
|
||||
$html .= $parent->renderHtml($view);
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Module\Businessprocess\Exception\NestingError;
|
||||
|
||||
class BpNode extends Node
|
||||
{
|
||||
|
|
@ -14,11 +14,16 @@ class BpNode extends Node
|
|||
protected $url;
|
||||
protected $info_command;
|
||||
protected $display = 0;
|
||||
|
||||
/** @var Node[] */
|
||||
protected $children;
|
||||
protected $child_names = array();
|
||||
|
||||
/** @var array */
|
||||
protected $childNames = array();
|
||||
protected $alias;
|
||||
protected $counters;
|
||||
protected $missing = null;
|
||||
protected $missingChildren;
|
||||
|
||||
protected static $emptyStateSummary = array(
|
||||
'OK' => 0,
|
||||
|
|
@ -42,7 +47,7 @@ class BpNode extends Node
|
|||
|
||||
protected $className = 'process';
|
||||
|
||||
public function __construct(BusinessProcess $bp, $object)
|
||||
public function __construct(BpConfig $bp, $object)
|
||||
{
|
||||
$this->bp = $bp;
|
||||
$this->name = $object->name;
|
||||
|
|
@ -56,7 +61,7 @@ class BpNode extends Node
|
|||
$this->getState();
|
||||
$this->counters = self::$emptyStateSummary;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
foreach ($this->getChildren() as $child) {
|
||||
if ($child instanceof BpNode) {
|
||||
$counters = $child->getStateSummary();
|
||||
foreach ($counters as $k => $v) {
|
||||
|
|
@ -88,6 +93,30 @@ class BpNode extends Node
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
* @return $this
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
public function addChild(Node $node)
|
||||
{
|
||||
if ($this->children === null) {
|
||||
$this->getChildren();
|
||||
}
|
||||
|
||||
$name = $node->getName();
|
||||
if (array_key_exists($name, $this->children)) {
|
||||
throw new ConfigurationError(
|
||||
'Node "%s" has been defined more than once',
|
||||
$name
|
||||
);
|
||||
}
|
||||
$this->children[$name] = $node;
|
||||
$this->childNames[] = $name;
|
||||
$node->addParent($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getProblematicChildren()
|
||||
{
|
||||
$problems = array();
|
||||
|
|
@ -103,6 +132,24 @@ class BpNode extends Node
|
|||
return $problems;
|
||||
}
|
||||
|
||||
public function hasChild($name)
|
||||
{
|
||||
return in_array($name, $this->childNames);
|
||||
}
|
||||
|
||||
public function removeChild($name)
|
||||
{
|
||||
if (($key = array_search($name, $this->childNames)) !== false) {
|
||||
unset($this->childNames[$key]);
|
||||
|
||||
if (! empty($this->children)) {
|
||||
unset($this->children[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getProblemTree()
|
||||
{
|
||||
$tree = array();
|
||||
|
|
@ -135,6 +182,27 @@ class BpNode extends Node
|
|||
return $this->missing;
|
||||
}
|
||||
|
||||
public function getMissingChildren()
|
||||
{
|
||||
if ($this->missingChildren === null) {
|
||||
$missing = array();
|
||||
|
||||
foreach ($this->getChildren() as $child) {
|
||||
if ($child->isMissing()) {
|
||||
$missing[(string) $child] = $child;
|
||||
}
|
||||
|
||||
foreach ($child->getMissingChildren() as $m) {
|
||||
$missing[(string) $m] = $m;
|
||||
}
|
||||
}
|
||||
|
||||
$this->missingChildren = $missing;
|
||||
}
|
||||
|
||||
return $this->missingChildren;
|
||||
}
|
||||
|
||||
public function getOperator()
|
||||
{
|
||||
return $this->operator;
|
||||
|
|
@ -174,7 +242,7 @@ class BpNode extends Node
|
|||
|
||||
public function hasInfoUrl()
|
||||
{
|
||||
return $this->url !== null;
|
||||
return ! empty($this->url);
|
||||
}
|
||||
|
||||
public function getInfoUrl()
|
||||
|
|
@ -213,26 +281,60 @@ class BpNode extends Node
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
if ($this->state === null) {
|
||||
$this->calculateState();
|
||||
try {
|
||||
$this->reCalculateState();
|
||||
} catch (NestingError $e) {
|
||||
$this->bp->addError(
|
||||
$this->bp->translate('Nesting error detected: %s'),
|
||||
$e->getMessage()
|
||||
);
|
||||
|
||||
// Failing nodes are unknown
|
||||
$this->state = 3;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function getHtmlId()
|
||||
{
|
||||
return 'businessprocess-' . preg_replace('/[\r\n\t\s]/', '_', (string) $this);
|
||||
}
|
||||
|
||||
protected function invertSortingState($state)
|
||||
{
|
||||
return self::$sortStateInversionMap[$state >> self::SHIFT_FLAGS] << self::SHIFT_FLAGS;
|
||||
}
|
||||
|
||||
protected function calculateState()
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function reCalculateState()
|
||||
{
|
||||
$bp = $this->bp;
|
||||
|
||||
$sort_states = array();
|
||||
$lastStateChange = 0;
|
||||
|
||||
if (!$this->hasChildren()) {
|
||||
// TODO: delegate this to operators, should mostly fail
|
||||
$this->state = 3;
|
||||
$this->setMissing();
|
||||
return $this;
|
||||
}
|
||||
|
||||
foreach ($this->getChildren() as $child) {
|
||||
$bp->beginLoopDetection($this->name);
|
||||
$sort_states[] = $child->getSortingState();
|
||||
$lastStateChange = max($lastStateChange, $child->getLastStateChange());
|
||||
$bp->endLoopDetection($this->name);
|
||||
}
|
||||
|
||||
$this->setLastStateChange($lastStateChange);
|
||||
|
|
@ -266,6 +368,21 @@ class BpNode extends Node
|
|||
}
|
||||
|
||||
$this->state = $this->sortStateTostate($sort_state);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function checkForLoops()
|
||||
{
|
||||
$bp = $this->bp;
|
||||
foreach ($this->getChildren() as $child) {
|
||||
$bp->beginLoopDetection($this->name);
|
||||
if ($child instanceof BpNode) {
|
||||
$child->checkForLoops();
|
||||
}
|
||||
$bp->endLoopDetection($this->name);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDisplay($display)
|
||||
|
|
@ -282,29 +399,51 @@ class BpNode extends Node
|
|||
public function setChildNames($names)
|
||||
{
|
||||
sort($names);
|
||||
$this->child_names = $names;
|
||||
$this->childNames = $names;
|
||||
$this->children = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasChildren($filter = null)
|
||||
{
|
||||
return !empty($this->childNames);
|
||||
}
|
||||
|
||||
public function getChildNames()
|
||||
{
|
||||
return $this->child_names;
|
||||
return $this->childNames;
|
||||
}
|
||||
|
||||
public function getChildren($filter = null)
|
||||
{
|
||||
if ($this->children === null) {
|
||||
$this->children = array();
|
||||
natsort($this->child_names);
|
||||
foreach ($this->child_names as $name) {
|
||||
natsort($this->childNames);
|
||||
foreach ($this->childNames as $name) {
|
||||
$this->children[$name] = $this->bp->getNode($name);
|
||||
$this->children[$name]->addParent($this);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* return BpNode[]
|
||||
*/
|
||||
public function getChildBpNodes()
|
||||
{
|
||||
$children = array();
|
||||
|
||||
foreach ($this->getChildren() as $name => $child) {
|
||||
if ($child instanceof BpNode) {
|
||||
$children[$name] = $child;
|
||||
}
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
protected function assertNumericOperator()
|
||||
{
|
||||
if (! is_numeric($this->operator)) {
|
||||
|
|
@ -312,76 +451,6 @@ class BpNode extends Node
|
|||
}
|
||||
}
|
||||
|
||||
protected function getActionIcons($view)
|
||||
{
|
||||
$icons = array();
|
||||
if (! $this->bp->isLocked() && $this->name !== '__unbound__') {
|
||||
$icons[] = $this->actionIcon(
|
||||
$view,
|
||||
'wrench',
|
||||
$view->url('businessprocess/node/edit', array(
|
||||
'config' => $this->bp->getName(),
|
||||
'node' => $this->name
|
||||
)),
|
||||
mt('businessprocess', 'Modify this node')
|
||||
);
|
||||
}
|
||||
return $icons;
|
||||
}
|
||||
|
||||
public function toLegacyConfigString(& $rendered = array())
|
||||
{
|
||||
$cfg = '';
|
||||
if (array_key_exists($this->name, $rendered)) {
|
||||
return $cfg;
|
||||
}
|
||||
$rendered[$this->name] = true;
|
||||
$children = array();
|
||||
|
||||
foreach ($this->getChildren() as $name => $child) {
|
||||
$children[] = (string) $child;
|
||||
if (array_key_exists($name, $rendered)) { continue; }
|
||||
if ($child instanceof BpNode) {
|
||||
$cfg .= $child->toLegacyConfigString($rendered) . "\n";
|
||||
}
|
||||
}
|
||||
$eq = '=';
|
||||
$op = $this->operator;
|
||||
if (is_numeric($op)) {
|
||||
$eq = '= ' . $op . ' of:';
|
||||
$op = '+';
|
||||
}
|
||||
|
||||
$strChildren = implode(' ' . $op . ' ', $children);
|
||||
if ((count($children) < 2) && $op !== '&') {
|
||||
$strChildren = $op . ' ' . $strChildren;
|
||||
}
|
||||
$cfg .= sprintf(
|
||||
"%s %s %s\n",
|
||||
$this->name,
|
||||
$eq,
|
||||
$strChildren
|
||||
);
|
||||
if ($this->hasAlias() || $this->getDisplay() > 0) {
|
||||
$prio = $this->getDisplay();
|
||||
$cfg .= sprintf(
|
||||
"display %s;%s;%s\n",
|
||||
$prio,
|
||||
$this->name,
|
||||
$this->getAlias()
|
||||
);
|
||||
}
|
||||
if ($this->hasInfoUrl()) {
|
||||
$cfg .= sprintf(
|
||||
"info_url;%s;%s\n",
|
||||
$this->name,
|
||||
$this->getInfoUrl()
|
||||
);
|
||||
}
|
||||
|
||||
return $cfg;
|
||||
}
|
||||
|
||||
public function operatorHtml()
|
||||
{
|
||||
switch ($this->operator) {
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use FineDiff;
|
||||
|
||||
class ConfigDiff
|
||||
{
|
||||
protected $a;
|
||||
|
||||
protected $b;
|
||||
|
||||
protected $diff;
|
||||
protected $opcodes;
|
||||
|
||||
protected function __construct($a, $b)
|
||||
{
|
||||
$this->a = $a;
|
||||
$this->b = $b;
|
||||
require_once dirname(__DIR__) . '/vendor/PHP-FineDiff/finediff.php';
|
||||
$granularity = FineDiff::$paragraphGranularity; // character, word, sentence, paragraph
|
||||
$this->diff = new FineDiff($a, $b, $granularity);
|
||||
}
|
||||
|
||||
public function renderHtml()
|
||||
{
|
||||
return $this->diff->renderDiffToHTML();
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->renderHtml();
|
||||
}
|
||||
|
||||
public static function create($a, $b)
|
||||
{
|
||||
$diff = new static($a, $b);
|
||||
return $diff;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Module\Businessprocess\Form\ProcessForm;
|
||||
use Icinga\Module\Businessprocess\Form\SimulationForm;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
use Icinga\Module\Monitoring\Backend;
|
||||
use Icinga\Web\Controller as ModuleController;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Module\Businessprocess\Web\Form\FormLoader;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\Widget;
|
||||
|
||||
class Controller extends ModuleController
|
||||
{
|
||||
protected $config;
|
||||
|
||||
protected $backend;
|
||||
|
||||
private $storage;
|
||||
|
||||
private $url;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$m = Icinga::app()->getModuleManager();
|
||||
if (! $m->hasLoaded('monitoring') && $m->hasInstalled('monitoring')) {
|
||||
$m->loadModule('monitoring');
|
||||
}
|
||||
$this->view->errors = array();
|
||||
|
||||
$this->view->compact = $this->params->get('view') === 'compact';
|
||||
}
|
||||
|
||||
protected function url()
|
||||
{
|
||||
if ($this->url === null) {
|
||||
$this->url = clone $this->getRequest()->getUrl();
|
||||
}
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
protected function tabs()
|
||||
{
|
||||
if ($this->view->tabs === null) {
|
||||
$this->view->tabs = Widget::create('tabs');
|
||||
}
|
||||
return $this->view->tabs;
|
||||
}
|
||||
|
||||
protected function session()
|
||||
{
|
||||
return $this->Window()->getSessionNamespace('businessprocess');
|
||||
}
|
||||
|
||||
protected function setTitle($title)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$this->view->title = vsprintf($title, $args);
|
||||
}
|
||||
|
||||
protected function loadModifiedBpConfig()
|
||||
{
|
||||
$bp = $this->loadBpConfig();
|
||||
$changes = ProcessChanges::construct($bp, $this->session());
|
||||
if ($this->params->get('dismissChanges')) {
|
||||
Notification::success(
|
||||
sprintf(
|
||||
$this->translate('%d pending change(s) have been dropped'),
|
||||
$changes->count()
|
||||
)
|
||||
);
|
||||
$changes->clear();
|
||||
$this->redirectNow($this->url()->without('dismissChanges')->without('unlocked'));
|
||||
}
|
||||
$bp->applyChanges($changes);
|
||||
return $bp;
|
||||
}
|
||||
|
||||
protected function loadBpConfig()
|
||||
{
|
||||
$storage = $this->storage();
|
||||
$this->view->processList = $storage->listProcesses();
|
||||
|
||||
// No process found? Go to welcome page
|
||||
if (empty($this->view->processList)) {
|
||||
$this->redirectNow('businessprocess');
|
||||
}
|
||||
|
||||
$name = $this->params->get(
|
||||
'config',
|
||||
key($this->view->processList)
|
||||
);
|
||||
|
||||
$modifications = $this->session()->get('modifications', array());
|
||||
if (array_key_exists($name, $modifications)) {
|
||||
$bp = $storage->loadFromString($name, $modifications[$name]);
|
||||
} else {
|
||||
$bp = $storage->loadProcess($name);
|
||||
}
|
||||
|
||||
// allow URL parameter to override configured state type
|
||||
if (null !== ($stateType = $this->params->get('state_type'))) {
|
||||
if ($stateType === 'soft') {
|
||||
$bp->useSoftStates();
|
||||
}
|
||||
if ($stateType === 'hard') {
|
||||
$bp->useHardStates();
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->bpconfig = $bp;
|
||||
$this->view->configName = $bp->getName();
|
||||
|
||||
return $bp;
|
||||
}
|
||||
|
||||
public function loadForm($name)
|
||||
{
|
||||
return FormLoader::load($name, $this->Module());
|
||||
}
|
||||
|
||||
protected function storage()
|
||||
{
|
||||
if ($this->storage === null) {
|
||||
$this->storage = new LegacyStorage(
|
||||
$this->Config()->getSection('global')
|
||||
);
|
||||
}
|
||||
|
||||
return $this->storage;
|
||||
}
|
||||
|
||||
protected function loadSlas()
|
||||
{
|
||||
$bpconf = $this->bpconf;
|
||||
|
||||
if (! isset($bpconf->slahosts)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// TODO: This doesn't work right now
|
||||
$sla_hosts = preg_split('~\s*,s*~', $bpconf->slahosts, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
if (isset($bpconf->sla_year)) {
|
||||
$start = mktime(0, 0, 0, 1, 1, $bpconf->sla_year);
|
||||
$end = mktime(23, 59, 59, 1, 0, $bpconf->sla_year + 1);
|
||||
} else {
|
||||
$start = mktime(0, 0, 0, 1, 1, (int) date('Y'));
|
||||
$end = null;
|
||||
// Bis zum Jahresende hochrechnen:
|
||||
// $end = mktime(23, 59, 59, 1, 0, (int) date('Y') + 1);
|
||||
}
|
||||
|
||||
return $this->backend
|
||||
->module('BpAddon')
|
||||
->getBpSlaValues($sla_hosts, $start, $end);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
namespace Icinga\Module\Businessprocess\Director;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Director\Web\Hook\ShipConfigFilesHook;
|
||||
use Icinga\Module\Director\Hook\ShipConfigFilesHook;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
|
||||
class ShipConfigFiles extends ShipConfigFilesHook
|
||||
|
|
|
|||
9
library/Businessprocess/Exception/NestingError.php
Normal file
9
library/Businessprocess/Exception/NestingError.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Exception;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
class NestingError extends IcingaException
|
||||
{
|
||||
}
|
||||
|
|
@ -2,25 +2,26 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
||||
class HostNode extends Node
|
||||
class HostNode extends MonitoredNode
|
||||
{
|
||||
protected static $sortStateToStateMap = array(
|
||||
protected $sortStateToStateMap = array(
|
||||
4 => self::ICINGA_DOWN,
|
||||
3 => self::ICINGA_UNREACHABLE,
|
||||
1 => self::ICINGA_PENDING,
|
||||
0 => self::ICINGA_UP
|
||||
);
|
||||
|
||||
protected static $stateToSortStateMap = array(
|
||||
protected $stateToSortStateMap = array(
|
||||
self::ICINGA_PENDING => 1,
|
||||
self::ICINGA_UNREACHABLE => 3,
|
||||
self::ICINGA_DOWN => 4,
|
||||
self::ICINGA_UP => 0,
|
||||
);
|
||||
|
||||
protected static $state_names = array(
|
||||
protected $stateNames = array(
|
||||
'UP',
|
||||
'DOWN',
|
||||
'UNREACHABLE',
|
||||
|
|
@ -31,7 +32,7 @@ class HostNode extends Node
|
|||
|
||||
protected $className = 'host';
|
||||
|
||||
public function __construct(BusinessProcess $bp, $object)
|
||||
public function __construct(BpConfig $bp, $object)
|
||||
{
|
||||
$this->name = $object->hostname . ';Hoststatus';
|
||||
$this->hostname = $object->hostname;
|
||||
|
|
@ -43,46 +44,31 @@ class HostNode extends Node
|
|||
}
|
||||
}
|
||||
|
||||
public function renderLink($view)
|
||||
public function getAlias()
|
||||
{
|
||||
if ($this->isMissing()) {
|
||||
return '<span class="missing">' . $view->escape($this->hostname) . '</span>';
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'host' => $this->getHostname(),
|
||||
);
|
||||
|
||||
if ($this->bp->hasBackendName()) {
|
||||
$params['backend'] = $this->bp->getBackendName();
|
||||
}
|
||||
return $view->qlink($this->hostname, 'monitoring/host/show', $params);
|
||||
}
|
||||
|
||||
protected function getActionIcons($view)
|
||||
{
|
||||
$icons = array();
|
||||
|
||||
if (! $this->bp->isLocked()) {
|
||||
|
||||
$url = Url::fromPath( 'businessprocess/node/simulate', array(
|
||||
'config' => $this->bp->getName(),
|
||||
'node' => $this->name
|
||||
));
|
||||
|
||||
$icons[] = $this->actionIcon(
|
||||
$view,
|
||||
'magic',
|
||||
$url,
|
||||
'Simulation'
|
||||
);
|
||||
}
|
||||
|
||||
return $icons;
|
||||
return $this->getHostname();
|
||||
}
|
||||
|
||||
public function getHostname()
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
$params = array(
|
||||
'host' => $this->getHostname(),
|
||||
);
|
||||
|
||||
if ($this->bp->hasBackendName()) {
|
||||
$params['backend'] = $this->bp->getBackendName();
|
||||
}
|
||||
|
||||
return Url::fromPath('monitoring/host/show', $params);
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
return Link::create($this->hostname, $this->getUrl());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
130
library/Businessprocess/Html/Attribute.php
Normal file
130
library/Businessprocess/Html/Attribute.php
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
class Attribute
|
||||
{
|
||||
/** @var string */
|
||||
protected $name;
|
||||
|
||||
/** @var string|array */
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* Attribute constructor.
|
||||
*
|
||||
* @param $name
|
||||
* @param $value
|
||||
*/
|
||||
public function __construct($name, $value)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return static
|
||||
*/
|
||||
public static function create($name, $value)
|
||||
{
|
||||
return new static($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addValue($value)
|
||||
{
|
||||
if (! is_array($this->value)) {
|
||||
$this->value = array($this->value);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$this->value = array_merge($this->value, $value);
|
||||
} else {
|
||||
$this->value[] = $value;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return sprintf(
|
||||
'%s="%s"',
|
||||
$this->renderName(),
|
||||
$this->renderValue()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function renderName()
|
||||
{
|
||||
return static::escapeName($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function renderValue()
|
||||
{
|
||||
return static::escapeValue($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return string
|
||||
*/
|
||||
public static function escapeName($name)
|
||||
{
|
||||
// TODO: escape
|
||||
return (string) $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
public static function escapeValue($value)
|
||||
{
|
||||
// TODO: escape differently
|
||||
if (is_array($value)) {
|
||||
return Util::escapeForHtml(implode(' ', $value));
|
||||
} else {
|
||||
return Util::escapeForHtml((string) $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
195
library/Businessprocess/Html/Attributes.php
Normal file
195
library/Businessprocess/Html/Attributes.php
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
class Attributes
|
||||
{
|
||||
/** @var Attribute[] */
|
||||
protected $attributes = array();
|
||||
|
||||
/** @var callable */
|
||||
protected $callbacks = array();
|
||||
|
||||
/**
|
||||
* Attributes constructor.
|
||||
* @param Attribute[] $attributes
|
||||
*/
|
||||
public function __construct(array $attributes = null)
|
||||
{
|
||||
if (empty($attributes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($attributes as $key => $value) {
|
||||
if ($value instanceof Attribute) {
|
||||
$this->addAttribute($value);
|
||||
} elseif (is_string($key)) {
|
||||
$this->add($key, $value);
|
||||
} elseif (is_array($value) && count($value) === 2) {
|
||||
$this->add(array_shift($value), array_shift($value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attribute[] $attributes
|
||||
* @return static
|
||||
*/
|
||||
public static function create(array $attributes = null)
|
||||
{
|
||||
return new static($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attributes|array|null $attributes
|
||||
* @return Attributes
|
||||
* @throws IcingaException
|
||||
*/
|
||||
public static function wantAttributes($attributes)
|
||||
{
|
||||
if ($attributes instanceof Attributes) {
|
||||
return $attributes;
|
||||
} else {
|
||||
$self = new static();
|
||||
if (is_array($attributes)) {
|
||||
foreach ($attributes as $k => $v) {
|
||||
$self->add($k, $v);
|
||||
}
|
||||
|
||||
return $self;
|
||||
|
||||
} elseif ($attributes !== null) {
|
||||
throw new IcingaException(
|
||||
'Attributes, Array or Null expected, got %s',
|
||||
Util::getPhpTypeName($attributes)
|
||||
);
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Attribute[]
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attribute|string $attribute
|
||||
* @param string|array $value
|
||||
* @return $this
|
||||
*/
|
||||
public function add($attribute, $value = null)
|
||||
{
|
||||
if ($attribute instanceof static) {
|
||||
foreach ($attribute->getAttributes() as $a) {
|
||||
$this->add($a);
|
||||
}
|
||||
} elseif ($attribute instanceof Attribute) {
|
||||
$this->addAttribute($attribute);
|
||||
} elseif (is_array($attribute)) {
|
||||
foreach ($attribute as $name => $value) {
|
||||
$this->add($name, $value);
|
||||
}
|
||||
} else {
|
||||
$this->addAttribute(Attribute::create($attribute, $value));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attribute|string $attribute
|
||||
* @param string|array $value
|
||||
* @return $this
|
||||
*/
|
||||
public function set($attribute, $value = null)
|
||||
{
|
||||
if ($attribute instanceof static) {
|
||||
foreach ($attribute as $a) {
|
||||
$this->setAttribute($a);
|
||||
}
|
||||
|
||||
return $this;
|
||||
} elseif ($attribute instanceof Attribute) {
|
||||
return $this->setAttribute($attribute);
|
||||
} else {
|
||||
return $this->setAttribute(new Attribute($attribute, $value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attribute $attribute
|
||||
* @return $this
|
||||
*/
|
||||
public function addAttribute(Attribute $attribute)
|
||||
{
|
||||
$name = $attribute->getName();
|
||||
if (array_key_exists($name, $this->attributes)) {
|
||||
$this->attributes[$name]->addValue($attribute->getValue());
|
||||
} else {
|
||||
$this->attributes[$name] = $attribute;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attribute $attribute
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute(Attribute $attribute)
|
||||
{
|
||||
$name = $attribute->getName();
|
||||
$this->attributes[$name] = $attribute;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback must return an instance of Attribute
|
||||
*
|
||||
* @param string $name
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function registerCallbackFor($name, $callback)
|
||||
{
|
||||
if (! is_callable($callback)) {
|
||||
throw new ProgrammingError('registerCallBack expects a callable callback');
|
||||
}
|
||||
$this->callbacks[$name] = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if (empty($this->attributes) && empty($this->callbacks)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$parts = array();
|
||||
foreach ($this->callbacks as $callback) {
|
||||
$attribute = call_user_func($callback);
|
||||
if (! $attribute instanceof Attribute) {
|
||||
throw new ProgrammingError(
|
||||
'A registered attribute callback must return an Attribute'
|
||||
);
|
||||
}
|
||||
|
||||
$parts[] = $attribute->render();
|
||||
}
|
||||
|
||||
foreach ($this->attributes as $attribute) {
|
||||
$parts[] = $attribute->render();
|
||||
}
|
||||
return ' ' . implode(' ', $parts);
|
||||
}
|
||||
}
|
||||
117
library/Businessprocess/Html/BaseElement.php
Normal file
117
library/Businessprocess/Html/BaseElement.php
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
use Exception;
|
||||
|
||||
abstract class BaseElement extends Html
|
||||
{
|
||||
/** @var array You may want to set default attributes when extending this class */
|
||||
protected $defaultAttributes;
|
||||
|
||||
/** @var Attributes */
|
||||
protected $attributes;
|
||||
|
||||
/** @var string */
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* @return Attributes
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
if ($this->attributes === null) {
|
||||
$default = $this->getDefaultAttributes();
|
||||
if (empty($default)) {
|
||||
$this->attributes = new Attributes();
|
||||
} else {
|
||||
$this->attributes = Attributes::wantAttributes($default);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attributes|array|null $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttributes($attributes)
|
||||
{
|
||||
$this->attributes = Attributes::wantAttributes($attributes);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attributes|array|null $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addAttributes($attributes)
|
||||
{
|
||||
$this->attributes = Attributes::wantAttributes($attributes);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultAttributes()
|
||||
{
|
||||
return $this->defaultAttributes;
|
||||
}
|
||||
|
||||
public function setTag($tag)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Container constructor.
|
||||
*
|
||||
* @param string $tag
|
||||
* @param Attributes|array $attributes
|
||||
*
|
||||
* @return Element
|
||||
*/
|
||||
public function createElement($tag, $attributes = null)
|
||||
{
|
||||
$element = Element::create($tag, $attributes);
|
||||
$this->add($element);
|
||||
return $element;
|
||||
}
|
||||
|
||||
public function renderContent()
|
||||
{
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$tag = $this->getTag();
|
||||
|
||||
return sprintf(
|
||||
'<%s%s>%s</%s>',
|
||||
$tag,
|
||||
$this->attributes()->render(),
|
||||
$this->renderContent(),
|
||||
$tag
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given something can be rendered
|
||||
*
|
||||
* @param mixed $any
|
||||
* @return bool
|
||||
*/
|
||||
protected function canBeRendered($any)
|
||||
{
|
||||
return is_string($any) || is_int($any) || is_null($any);
|
||||
}
|
||||
}
|
||||
40
library/Businessprocess/Html/Container.php
Normal file
40
library/Businessprocess/Html/Container.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
class Container extends BaseElement
|
||||
{
|
||||
/** @var string */
|
||||
protected $contentSeparator = "\n";
|
||||
|
||||
/** @var string */
|
||||
protected $tag = 'div';
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Renderable|array|string $content
|
||||
* @param Attributes|array $attributes
|
||||
* @param string $tag
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($attributes = null, $content = null, $tag = null)
|
||||
{
|
||||
$container = new static();
|
||||
if ($content !== null) {
|
||||
$container->setContent($content);
|
||||
}
|
||||
|
||||
if ($attributes !== null) {
|
||||
$container->setAttributes($attributes);
|
||||
}
|
||||
if ($tag !== null) {
|
||||
$container->setTag($tag);
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
}
|
||||
34
library/Businessprocess/Html/Element.php
Normal file
34
library/Businessprocess/Html/Element.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
class Element extends BaseElement
|
||||
{
|
||||
/**
|
||||
* Container constructor.
|
||||
*
|
||||
* @param string $tag
|
||||
* @param Attributes|array $attributes
|
||||
*/
|
||||
public function __construct($tag, $attributes = null)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
|
||||
if ($attributes !== null) {
|
||||
$this->attributes = $this->attributes()->add($attributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Container constructor.
|
||||
*
|
||||
* @param string $tag
|
||||
* @param Attributes|array $attributes
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($tag, $attributes = null)
|
||||
{
|
||||
return new static($tag, $attributes);
|
||||
}
|
||||
}
|
||||
157
library/Businessprocess/Html/Html.php
Normal file
157
library/Businessprocess/Html/Html.php
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
class Html implements Renderable
|
||||
{
|
||||
protected $contentSeparator = '';
|
||||
|
||||
/**
|
||||
* @var Renderable[]
|
||||
*/
|
||||
private $content = array();
|
||||
|
||||
public static function escape($any)
|
||||
{
|
||||
return Util::wantHtml($any);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Renderable $element
|
||||
* @return $this
|
||||
*/
|
||||
public function add(Renderable $element)
|
||||
{
|
||||
$this->content[] = $element;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Renderable|array|string $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setContent($content)
|
||||
{
|
||||
$this->content = array(
|
||||
static::escape($content)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Renderable|array|string $content
|
||||
* @return $this
|
||||
*/
|
||||
public function addContent($content)
|
||||
{
|
||||
$this->content[] = static::escape($content);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Renderable|array|string $content
|
||||
* @return $this
|
||||
*/
|
||||
public function prependContent($content)
|
||||
{
|
||||
array_unshift($this->content, static::escape($content));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* return Html
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
if ($this->content === null) {
|
||||
$this->content = array(new Html());
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function hasContent()
|
||||
{
|
||||
if ($this->content === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: unfinished
|
||||
// return $this->content->isEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $separator
|
||||
* @return $this
|
||||
*/
|
||||
public function setSeparator($separator)
|
||||
{
|
||||
$this->contentSeparator = $separator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$html = array();
|
||||
|
||||
foreach ($this->content as $element) {
|
||||
if (is_string($element)) {
|
||||
var_dump($this->content);
|
||||
}
|
||||
$html[] = $element->render();
|
||||
}
|
||||
|
||||
return implode($this->contentSeparator, $html);
|
||||
}
|
||||
|
||||
protected function translate($msg)
|
||||
{
|
||||
// TODO: Not so nice
|
||||
return mt('businessprocess', $msg);
|
||||
}
|
||||
|
||||
public static function element($name, $attributes = null)
|
||||
{
|
||||
// TODO: This might be anything here, add a better check
|
||||
if (! ctype_alnum($name)) {
|
||||
throw new ProgrammingError('Invalid element requested');
|
||||
}
|
||||
|
||||
$class = __NAMESPACE__ . '\\' . $name;
|
||||
/** @var Element $element */
|
||||
$element = new $class();
|
||||
if ($attributes !== null) {
|
||||
$element->setAttributes($attributes);
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception|string $error
|
||||
* @return string
|
||||
*/
|
||||
protected function renderError($error)
|
||||
{
|
||||
return Util::renderError($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
return $this->render();
|
||||
} catch (Exception $e) {
|
||||
return $this->renderError($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
library/Businessprocess/Html/HtmlString.php
Normal file
8
library/Businessprocess/Html/HtmlString.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
class HtmlString extends Text
|
||||
{
|
||||
protected $escaped = true;
|
||||
}
|
||||
28
library/Businessprocess/Html/HtmlTag.php
Normal file
28
library/Businessprocess/Html/HtmlTag.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
abstract class HtmlTag
|
||||
{
|
||||
/**
|
||||
* @param $content
|
||||
* @param Attributes|array $attributes
|
||||
*
|
||||
* @return Element
|
||||
*/
|
||||
public static function h1($content, $attributes = null)
|
||||
{
|
||||
return Element::create('h1', $attributes)->setContent($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @param Attributes|array $attributes
|
||||
*
|
||||
* @return Element
|
||||
*/
|
||||
public static function p($content, $attributes = null)
|
||||
{
|
||||
return Element::create('p', $attributes)->setContent($content);
|
||||
}
|
||||
}
|
||||
26
library/Businessprocess/Html/Icon.php
Normal file
26
library/Businessprocess/Html/Icon.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
class Icon extends BaseElement
|
||||
{
|
||||
protected $tag = 'i';
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($name, array $attributes = null)
|
||||
{
|
||||
$icon = new static();
|
||||
$icon->setAttributes($attributes);
|
||||
$icon->attributes()->add('class', array('icon', 'icon-' . $name));
|
||||
return $icon;
|
||||
}
|
||||
}
|
||||
72
library/Businessprocess/Html/Img.php
Normal file
72
library/Businessprocess/Html/Img.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
use Icinga\Web\Url as WebUrl;
|
||||
|
||||
class Img extends BaseElement
|
||||
{
|
||||
protected $tag = 'img';
|
||||
|
||||
/** @var Url */
|
||||
protected $url;
|
||||
|
||||
protected $defaultAttributes = array('alt' => '');
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Url|string $url
|
||||
* @param array $urlParams
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($url, $urlParams = null, array $attributes = null)
|
||||
{
|
||||
$img = new static();
|
||||
$img->setAttributes($attributes);
|
||||
$img->attributes()->registerCallbackFor('src', array($img, 'getSrcAttribute'));
|
||||
$img->setUrl($url, $urlParams);
|
||||
return $img;
|
||||
}
|
||||
|
||||
public function setUrl($url, $urlParams)
|
||||
{
|
||||
if ($url instanceof WebUrl) { // Hint: Url is also a WebUrl
|
||||
if ($urlParams !== null) {
|
||||
$url->addParams($urlParams);
|
||||
}
|
||||
|
||||
$this->url = $url;
|
||||
} else {
|
||||
if ($urlParams === null) {
|
||||
$this->url = Url::fromPath($url);
|
||||
} else {
|
||||
$this->url = Url::fromPath($url, $urlParams);
|
||||
}
|
||||
}
|
||||
|
||||
$this->url->getParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Attribute
|
||||
*/
|
||||
public function getSrcAttribute()
|
||||
{
|
||||
return new Attribute('src', $this->getUrl()->getAbsoluteUrl('&'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Url
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
// TODO: What if null? #?
|
||||
return $this->url;
|
||||
}
|
||||
}
|
||||
72
library/Businessprocess/Html/Link.php
Normal file
72
library/Businessprocess/Html/Link.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
use Icinga\Web\Url as WebUrl;
|
||||
|
||||
class Link extends BaseElement
|
||||
{
|
||||
protected $tag = 'a';
|
||||
|
||||
/** @var Url */
|
||||
protected $url;
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Renderable|array|string $content
|
||||
* @param Url|string $url
|
||||
* @param array $urlParams
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($content, $url, $urlParams = null, array $attributes = null)
|
||||
{
|
||||
$link = new static();
|
||||
$link->setContent($content);
|
||||
$link->setAttributes($attributes);
|
||||
$link->attributes()->registerCallbackFor('href', array($link, 'getHrefAttribute'));
|
||||
$link->setUrl($url, $urlParams);
|
||||
return $link;
|
||||
}
|
||||
|
||||
public function setUrl($url, $urlParams)
|
||||
{
|
||||
if ($url instanceof WebUrl) { // Hint: Url is also a WebUrl
|
||||
if ($urlParams !== null) {
|
||||
$url->addParams($urlParams);
|
||||
}
|
||||
|
||||
$this->url = $url;
|
||||
} else {
|
||||
if ($urlParams === null) {
|
||||
$this->url = Url::fromPath($url);
|
||||
} else {
|
||||
$this->url = Url::fromPath($url, $urlParams);
|
||||
}
|
||||
}
|
||||
|
||||
$this->url->getParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Attribute
|
||||
*/
|
||||
public function getHrefAttribute()
|
||||
{
|
||||
return new Attribute('href', $this->getUrl()->getAbsoluteUrl('&'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Url
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
// TODO: What if null? #?
|
||||
return $this->url;
|
||||
}
|
||||
}
|
||||
8
library/Businessprocess/Html/Renderable.php
Normal file
8
library/Businessprocess/Html/Renderable.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
interface Renderable
|
||||
{
|
||||
public function render();
|
||||
}
|
||||
82
library/Businessprocess/Html/Text.php
Normal file
82
library/Businessprocess/Html/Text.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
class Text implements Renderable
|
||||
{
|
||||
/** @var string */
|
||||
protected $string;
|
||||
|
||||
protected $escaped = false;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
*
|
||||
* @param $text
|
||||
*/
|
||||
public function __construct($string)
|
||||
{
|
||||
$this->string = (string) $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
return $this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $escaped
|
||||
* @return $this
|
||||
*/
|
||||
public function setEscaped($escaped = true)
|
||||
{
|
||||
$this->escaped = $escaped;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $text
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($text)
|
||||
{
|
||||
return new static($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if ($this->escaped) {
|
||||
return $this->string;
|
||||
} else {
|
||||
return Util::escapeForHtml($this->string);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception|string $error
|
||||
* @return string
|
||||
*/
|
||||
protected function renderError($error)
|
||||
{
|
||||
return Util::renderError($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
return $this->render();
|
||||
} catch (Exception $e) {
|
||||
return $this->renderError($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
130
library/Businessprocess/Html/Util.php
Normal file
130
library/Businessprocess/Html/Util.php
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Html;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* Charset to be used - we only support UTF-8
|
||||
*/
|
||||
const CHARSET = 'UTF-8';
|
||||
|
||||
/**
|
||||
* The flags we use for htmlspecialchars depend on our PHP version
|
||||
*/
|
||||
protected static $htmlEscapeFlags;
|
||||
|
||||
/**
|
||||
* Escape the given value top be safely used in view scripts
|
||||
*
|
||||
* @param string $value The output to be escaped
|
||||
* @return string
|
||||
*/
|
||||
public static function escapeForHtml($value)
|
||||
{
|
||||
return htmlspecialchars(
|
||||
$value,
|
||||
static::htmlEscapeFlags(),
|
||||
self::CHARSET,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception|string $error
|
||||
* @return string
|
||||
*/
|
||||
public static function renderError($error)
|
||||
{
|
||||
if ($error instanceof Exception) {
|
||||
$file = preg_split('/[\/\\\]/', $error->getFile(), -1, PREG_SPLIT_NO_EMPTY);
|
||||
$file = array_pop($file);
|
||||
$msg = sprintf(
|
||||
'%s (%s:%d)',
|
||||
$error->getMessage(),
|
||||
$file,
|
||||
$error->getLine()
|
||||
);
|
||||
} elseif (is_string($error)) {
|
||||
$msg = $error;
|
||||
} else {
|
||||
$msg = 'Got an invalid error'; // TODO: translate?
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'ERROR: %s', // TODO: translate?
|
||||
static::escapeForHtml($msg)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $any
|
||||
* @return Renderable
|
||||
* @throws IcingaException
|
||||
*/
|
||||
public static function wantHtml($any)
|
||||
{
|
||||
if ($any instanceof Renderable) {
|
||||
return $any;
|
||||
} elseif (static::canBeRenderedAsString($any)) {
|
||||
return new Text($any);
|
||||
} elseif (is_array($any)) {
|
||||
$html = new Html();
|
||||
foreach ($any as $el) {
|
||||
$html->add(static::wantHtml($el));
|
||||
}
|
||||
|
||||
return $html;
|
||||
} else {
|
||||
// TODO: Should we add a dedicated Exception class?
|
||||
throw new IcingaException(
|
||||
'String, Html Element or Array of such expected, got "%s"',
|
||||
Util::getPhpTypeName($any)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function canBeRenderedAsString($any)
|
||||
{
|
||||
return is_string($any) || is_int($any) || is_null($any);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $any
|
||||
* @return string
|
||||
*/
|
||||
public static function getPhpTypeName($any)
|
||||
{
|
||||
if (is_object($any)) {
|
||||
return get_class($any);
|
||||
} else {
|
||||
return gettype($any);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This defines the flags used when escaping for HTML
|
||||
*
|
||||
* - Single quotes are not escaped (ENT_COMPAT)
|
||||
* - With PHP >= 5.4, invalid characters are replaced with <EFBFBD> (ENT_SUBSTITUTE)
|
||||
* - With PHP 5.3 they are ignored (ENT_IGNORE, less secure)
|
||||
* - Uses HTML5 entities for PHP >= 5.4, disallowing 
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected static function htmlEscapeFlags()
|
||||
{
|
||||
if (self::$htmlEscapeFlags === null) {
|
||||
if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
|
||||
self::$htmlEscapeFlags = ENT_COMPAT | ENT_SUBSTITUTE | ENT_HTML5;
|
||||
} else {
|
||||
self::$htmlEscapeFlags = ENT_COMPAT | ENT_IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$htmlEscapeFlags;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,25 +3,42 @@
|
|||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
use Exception;
|
||||
|
||||
class ImportedNode extends Node
|
||||
{
|
||||
/** @var string */
|
||||
protected $configName;
|
||||
|
||||
protected $importedBp;
|
||||
/** @var string */
|
||||
protected $nodeName;
|
||||
|
||||
protected $importedNode;
|
||||
/** @var BpNode */
|
||||
private $node;
|
||||
|
||||
protected $className = 'subtree';
|
||||
|
||||
public function __construct(BusinessProcess $bp, $object)
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __construct(BpConfig $bp, $object)
|
||||
{
|
||||
$this->name = $object->name;
|
||||
$this->bp = $bp;
|
||||
$this->configName = $object->configName;
|
||||
$this->bp = $bp;
|
||||
$this->name = '@' . $object->configName;
|
||||
if (property_exists($object, 'node')) {
|
||||
$this->nodeName = $object->node;
|
||||
$this->name .= ':' . $object->node;
|
||||
} else {
|
||||
$this->useAllRootNodes();
|
||||
}
|
||||
|
||||
if (isset($object->state)) {
|
||||
$this->setState($object->state);
|
||||
} else {
|
||||
|
|
@ -29,108 +46,189 @@ class ImportedNode extends Node
|
|||
}
|
||||
}
|
||||
|
||||
public function hasNode()
|
||||
{
|
||||
return $this->nodeName !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigName()
|
||||
{
|
||||
return $this->configName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
if ($this->state === null) {
|
||||
try {
|
||||
$this->importedConfig()->retrieveStatesFromBackend();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
$this->state = $this->importedNode()->getState();
|
||||
}
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAlias()
|
||||
{
|
||||
return $this->importedNode()->getAlias();
|
||||
}
|
||||
|
||||
public function isMissing()
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->importedNode()->isMissing();
|
||||
// TODO: WHY? return $this->getState() === null;
|
||||
$params = array(
|
||||
'config' => $this->getConfigName(),
|
||||
'node' => $this->importedNode()->getName()
|
||||
);
|
||||
|
||||
return Url::fromPath('businessprocess/process/show', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isMissing()
|
||||
{
|
||||
// TODO: WHY? return $this->getState() === null;
|
||||
return $this->importedNode()->isMissing();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isInDowntime()
|
||||
{
|
||||
if ($this->downtime === null) {
|
||||
$this->getState();
|
||||
$this->downtime = $this->importedNode()->isInDowntime();
|
||||
}
|
||||
|
||||
return $this->downtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isAcknowledged()
|
||||
{
|
||||
if ($this->ack === null) {
|
||||
$this->getState();
|
||||
$this->downtime = $this->importedNode()->isAcknowledged();
|
||||
}
|
||||
|
||||
return $this->ack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode
|
||||
*/
|
||||
protected function importedNode()
|
||||
{
|
||||
if ($this->importedNode === null) {
|
||||
$storage = new LegacyStorage(
|
||||
Config::module('businessprocess')->getSection('global')
|
||||
);
|
||||
try {
|
||||
$this->importedBp = $storage->loadProcess($this->configName);
|
||||
if ($this->bp->usesSoftStates()) {
|
||||
$this->importedBp->useSoftStates();
|
||||
} else {
|
||||
$this->importedBp->useHardStates();
|
||||
}
|
||||
$this->importedBp->retrieveStatesFromBackend();
|
||||
$this->importedNode = $this->importedBp->getNode($this->name);
|
||||
} catch (Exception $e) {
|
||||
|
||||
|
||||
$node = new BpNode($this->bp, (object) array(
|
||||
'name' => $this->name,
|
||||
'operator' => '&',
|
||||
'child_names' => array()
|
||||
));
|
||||
$node->setState(2);
|
||||
$node->setMissing(false)
|
||||
->setDowntime(false)
|
||||
->setAck(false)
|
||||
->setAlias($e->getMessage());
|
||||
|
||||
$this->importedNode = $node;
|
||||
}
|
||||
if ($this->node === null) {
|
||||
$this->node = $this->loadImportedNode();
|
||||
}
|
||||
return $this->importedNode;
|
||||
|
||||
return $this->node;
|
||||
}
|
||||
|
||||
protected function getActionIcons($view)
|
||||
|
||||
/**
|
||||
* @return BpNode
|
||||
*/
|
||||
protected function loadImportedNode()
|
||||
{
|
||||
$icons = array();
|
||||
try {
|
||||
$import = $this->importedConfig();
|
||||
|
||||
if (! $this->bp->isLocked()) {
|
||||
return $import->getNode($this->nodeName);
|
||||
} catch (Exception $e) {
|
||||
return $this->createFailedNode($e);
|
||||
}
|
||||
}
|
||||
|
||||
$url = Url::fromPath( 'businessprocess/node/simulate', array(
|
||||
'config' => $this->bp->getName(),
|
||||
'node' => $this->name
|
||||
protected function useAllRootNodes()
|
||||
{
|
||||
try {
|
||||
$bp = $this->importedConfig();
|
||||
$this->node = new BpNode($bp, (object) array(
|
||||
'name' => $this->getName(),
|
||||
'operator' => '&',
|
||||
'child_names' => $bp->listRootNodes(),
|
||||
));
|
||||
} catch (Exception $e) {
|
||||
|
||||
$icons[] = $this->actionIcon(
|
||||
$view,
|
||||
'magic',
|
||||
$url,
|
||||
'Simulation'
|
||||
);
|
||||
$this->createFailedNode($e);
|
||||
}
|
||||
|
||||
return $icons;
|
||||
}
|
||||
|
||||
public function renderLink($view)
|
||||
protected function importedConfig()
|
||||
{
|
||||
return $view->qlink($this->getAlias(), 'businessprocess/process/show', array(
|
||||
'config' => $this->configName,
|
||||
'process' => $this->name
|
||||
if ($this->config === null) {
|
||||
$import = $this->storage()->loadProcess($this->configName);
|
||||
if ($this->bp->usesSoftStates()) {
|
||||
$import->useSoftStates();
|
||||
} else {
|
||||
$import->useHardStates();
|
||||
}
|
||||
|
||||
$this->config = $import;
|
||||
}
|
||||
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LegacyStorage
|
||||
*/
|
||||
protected function storage()
|
||||
{
|
||||
return new LegacyStorage(
|
||||
Config::module('businessprocess')->getSection('global')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $e
|
||||
*
|
||||
* @return BpNode
|
||||
*/
|
||||
protected function createFailedNode(Exception $e)
|
||||
{
|
||||
$this->bp->addError($e->getMessage());
|
||||
$node = new BpNode($this->importedConfig(), (object) array(
|
||||
'name' => $this->getName(),
|
||||
'operator' => '&',
|
||||
'child_names' => array()
|
||||
));
|
||||
$node->setState(2);
|
||||
$node->setMissing(false)
|
||||
->setDowntime(false)
|
||||
->setAck(false)
|
||||
->setAlias($e->getMessage());
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
return Link::create(
|
||||
$this->getAlias(),
|
||||
'businessprocess/process/show',
|
||||
array(
|
||||
'config' => $this->configName,
|
||||
'process' => $this->name
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
244
library/Businessprocess/Metadata.php
Normal file
244
library/Businessprocess/Metadata.php
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\User;
|
||||
|
||||
class Metadata
|
||||
{
|
||||
/** @var string Configuration name */
|
||||
protected $name;
|
||||
|
||||
protected $properties = array(
|
||||
'Title' => null,
|
||||
'Description' => null,
|
||||
'Owner' => null,
|
||||
'AllowedUsers' => null,
|
||||
'AllowedGroups' => null,
|
||||
'AllowedRoles' => null,
|
||||
'AddToMenu' => null,
|
||||
'Backend' => null,
|
||||
'Statetype' => null,
|
||||
// 'SLAHosts' => null
|
||||
);
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
if ($this->has('Title')) {
|
||||
return $this->get('Title');
|
||||
} else {
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
public function getExtendedTitle()
|
||||
{
|
||||
$title = $this->getTitle();
|
||||
|
||||
if ($title === $this->name) {
|
||||
return $title;
|
||||
} else {
|
||||
return sprintf('%s (%s)', $title, $this->name);
|
||||
}
|
||||
}
|
||||
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
public function hasKey($key)
|
||||
{
|
||||
return array_key_exists($key, $this->properties);
|
||||
}
|
||||
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$this->assertKeyExists($key);
|
||||
if ($this->properties[$key] === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->properties[$key];
|
||||
}
|
||||
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->assertKeyExists($key);
|
||||
$this->properties[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isNull($key)
|
||||
{
|
||||
return null === $this->get($key);
|
||||
}
|
||||
|
||||
public function has($key)
|
||||
{
|
||||
return null !== $this->get($key);
|
||||
}
|
||||
|
||||
protected function assertKeyExists($key)
|
||||
{
|
||||
if (! $this->hasKey($key)) {
|
||||
throw new ProgrammingError('Trying to access invalid header key: %s', $key);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasRestrictions()
|
||||
{
|
||||
return ! (
|
||||
$this->isNull('AllowedUsers')
|
||||
&& $this->isNull('AllowedGroups')
|
||||
&& $this->isNull('AllowedRoles')
|
||||
);
|
||||
}
|
||||
|
||||
protected function getAuth()
|
||||
{
|
||||
return Auth::getInstance();
|
||||
}
|
||||
|
||||
public function canModify(Auth $auth = null)
|
||||
{
|
||||
if ($auth === null) {
|
||||
if (Icinga::app()->isCli()) {
|
||||
return true;
|
||||
} else {
|
||||
$auth = $this->getAuth();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->canRead($auth) && (
|
||||
$auth->hasPermission('businessprocess/modify')
|
||||
|| $this->ownerIs($auth->getUser()->getUsername())
|
||||
);
|
||||
}
|
||||
|
||||
public function canRead(Auth $auth = null)
|
||||
{
|
||||
if ($auth === null) {
|
||||
if (Icinga::app()->isCli()) {
|
||||
return true;
|
||||
} else {
|
||||
$auth = $this->getAuth();
|
||||
}
|
||||
}
|
||||
|
||||
if ($auth->hasPermission('businessprocess/showall')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $this->hasRestrictions()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $auth->isAuthenticated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->userCanRead($auth->getUser());
|
||||
}
|
||||
|
||||
protected function userCanRead(User $user)
|
||||
{
|
||||
$username = $user->getUsername();
|
||||
|
||||
return $this->ownerIs($username)
|
||||
|| $this->isInAllowedUserList($username)
|
||||
|| $this->isMemberOfAllowedGroups($user)
|
||||
|| $this->hasOneOfTheAllowedRoles($user);
|
||||
}
|
||||
|
||||
public function ownerIs($username)
|
||||
{
|
||||
return $this->get('Owner') === $username;
|
||||
}
|
||||
|
||||
public function listAllowedUsers()
|
||||
{
|
||||
// TODO: $this->get('AllowedUsers', array());
|
||||
$list = $this->get('AllowedUsers');
|
||||
if ($list === null) {
|
||||
return array();
|
||||
} else {
|
||||
return $this->splitCommaSeparated($list);
|
||||
}
|
||||
}
|
||||
|
||||
public function listAllowedGroups()
|
||||
{
|
||||
$list = $this->get('AllowedGroups');
|
||||
if ($list === null) {
|
||||
return array();
|
||||
} else {
|
||||
return $this->splitCommaSeparated($list);
|
||||
}
|
||||
}
|
||||
|
||||
public function listAllowedRoles()
|
||||
{
|
||||
$list = $this->get('AllowedRoles');
|
||||
if ($list === null) {
|
||||
return array();
|
||||
} else {
|
||||
return $this->splitCommaSeparated($list);
|
||||
}
|
||||
}
|
||||
|
||||
public function isInAllowedUserList($username)
|
||||
{
|
||||
foreach ($this->listAllowedUsers() as $allowedUser) {
|
||||
if ($username === $allowedUser) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isMemberOfAllowedGroups(User $user)
|
||||
{
|
||||
foreach ($this->listAllowedGroups() as $groups) {
|
||||
foreach ($groups as $group) {
|
||||
if ($user->isMemberOf($group)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasOneOfTheAllowedRoles(User $user)
|
||||
{
|
||||
foreach ($this->listAllowedRoles() as $roles) {
|
||||
foreach ($roles as $roleName) {
|
||||
foreach ($user->getRoles() as $role) {
|
||||
if ($role->getName() === $roleName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function splitCommaSeparated($string)
|
||||
{
|
||||
return preg_split('/\s*,\s*/', $string, -1, PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
}
|
||||
160
library/Businessprocess/Modification/NodeAction.php
Normal file
160
library/Businessprocess/Modification/NodeAction.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Modification;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
/**
|
||||
* Abstract NodeAction class
|
||||
*
|
||||
* Every instance of a NodeAction represents a single applied change. Changes are pushed to
|
||||
* a stack and consumed from there. When persisted, NodeActions are serialized with their name,
|
||||
* node name and optionally additional properties according preserveProperties. For each property
|
||||
* that should be preserved, getter and setter methods have to be defined.
|
||||
*
|
||||
* @package Icinga\Module\Businessprocess
|
||||
*/
|
||||
abstract class NodeAction
|
||||
{
|
||||
/** @var string Name of this action (currently create, modify, remove) */
|
||||
protected $actionName;
|
||||
|
||||
/** @var string Name of the node this action applies to */
|
||||
protected $nodeName;
|
||||
|
||||
/** @var array Properties which should be preserved when serializing this action */
|
||||
protected $preserveProperties = array();
|
||||
|
||||
/**
|
||||
* NodeAction constructor.
|
||||
*
|
||||
* @param Node|string $node
|
||||
*/
|
||||
public function __construct($node = null)
|
||||
{
|
||||
if ($node !== null) {
|
||||
$this->nodeName = (string) $node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Every NodeAction must be able to apply itself to a BusinessProcess
|
||||
*
|
||||
* @param BpConfig $config
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function applyTo(BpConfig $config);
|
||||
|
||||
/**
|
||||
* Every NodeAction must be able to tell whether it could be applied to a BusinessProcess
|
||||
*
|
||||
* @param BpConfig $config
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function appliesTo(BpConfig $config);
|
||||
|
||||
/**
|
||||
* The name of the node this modification applies to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeName()
|
||||
{
|
||||
return $this->nodeName;
|
||||
}
|
||||
|
||||
public function hasNode()
|
||||
{
|
||||
return $this->nodeName !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this is an instance of a given action name
|
||||
*
|
||||
* @param string $actionName
|
||||
* @return bool
|
||||
*/
|
||||
public function is($actionName)
|
||||
{
|
||||
return $this->getActionName() === $actionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of a given actionName for a specific Node
|
||||
*
|
||||
* @param string $actionName
|
||||
* @param string $nodeName
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($actionName, $nodeName)
|
||||
{
|
||||
$className = __NAMESPACE__ . '\\Node' . ucfirst($actionName) . 'Action';
|
||||
$object = new $className($nodeName);
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded serialized NodeAction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
$object = (object) array(
|
||||
'actionName' => $this->getActionName(),
|
||||
'nodeName' => $this->getNodeName(),
|
||||
'properties' => array()
|
||||
);
|
||||
|
||||
foreach ($this->preserveProperties as $key) {
|
||||
$func = 'get' . ucfirst($key);
|
||||
$object->properties[$key] = $this->$func();
|
||||
}
|
||||
|
||||
return json_encode($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a JSON-serialized NodeAction and returns an object instance
|
||||
*
|
||||
* @param $string
|
||||
* @return NodeAction
|
||||
*/
|
||||
public static function unSerialize($string)
|
||||
{
|
||||
$object = json_decode($string);
|
||||
$action = self::create($object->actionName, $object->nodeName);
|
||||
|
||||
foreach ($object->properties as $key => $val) {
|
||||
$func = 'set' . ucfirst($key);
|
||||
$action->$func($val);
|
||||
}
|
||||
|
||||
return $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the defined action name or determines such from the class name
|
||||
*
|
||||
* @return string The action name
|
||||
*
|
||||
* @throws ProgrammingError when no such class exists
|
||||
*/
|
||||
public function getActionName()
|
||||
{
|
||||
if ($this->actionName === null) {
|
||||
if (! preg_match('/\\\Node(\w+)Action$/', get_class($this), $m)) {
|
||||
throw new ProgrammingError(
|
||||
'"%s" is not a NodeAction class',
|
||||
get_class($this)
|
||||
);
|
||||
}
|
||||
$this->actionName = lcfirst($m[1]);
|
||||
}
|
||||
|
||||
return $this->actionName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Modification;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
|
||||
class NodeAddChildrenAction extends NodeAction
|
||||
{
|
||||
protected $children = array();
|
||||
|
||||
protected $preserveProperties = array('children');
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function appliesTo(BpConfig $config)
|
||||
{
|
||||
$name = $this->getNodeName();
|
||||
|
||||
if (! $config->hasNode($name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $config->getNode($name) instanceof BpNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function applyTo(BpConfig $config)
|
||||
{
|
||||
/** @var BpNode $node */
|
||||
if (! $this->hasNode()) {
|
||||
// TODO: We end up here when defining "top nodes", but that would probably
|
||||
// be a different action
|
||||
return $this;
|
||||
}
|
||||
|
||||
$node = $config->getBpNode($this->getNodeName());
|
||||
|
||||
foreach ($this->children as $name) {
|
||||
if (! $config->hasNode($name)) {
|
||||
if (strpos($name, ';') !== false) {
|
||||
list($host, $service) = preg_split('/;/', $name, 2);
|
||||
|
||||
if ($service === 'Hoststatus') {
|
||||
$config->createHost($host);
|
||||
} else {
|
||||
$config->createService($host, $service);
|
||||
}
|
||||
}
|
||||
}
|
||||
$node->addChild($config->getNode($name));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $children
|
||||
* @return $this
|
||||
*/
|
||||
public function setChildren($children)
|
||||
{
|
||||
if (is_string($children)) {
|
||||
$children = array($children);
|
||||
}
|
||||
$this->children = $children;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
}
|
||||
109
library/Businessprocess/Modification/NodeCreateAction.php
Normal file
109
library/Businessprocess/Modification/NodeCreateAction.php
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Modification;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
|
||||
class NodeCreateAction extends NodeAction
|
||||
{
|
||||
/** @var string */
|
||||
protected $parentName;
|
||||
|
||||
/** @var array */
|
||||
protected $properties = array();
|
||||
|
||||
/** @var array */
|
||||
protected $preserveProperties = array('parentName', 'properties');
|
||||
|
||||
/**
|
||||
* @param Node $name
|
||||
*/
|
||||
public function setParent(Node $name)
|
||||
{
|
||||
$this->parentName = (string) $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasParent()
|
||||
{
|
||||
return $this->parentName !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getParentName()
|
||||
{
|
||||
return $this->parentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function setParentName($name)
|
||||
{
|
||||
$this->parentName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $properties
|
||||
* @return $this
|
||||
*/
|
||||
public function setProperties($properties)
|
||||
{
|
||||
$this->properties = (array) $properties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function appliesTo(BpConfig $config)
|
||||
{
|
||||
return ! $config->hasNode($this->getNodeName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function applyTo(BpConfig $config)
|
||||
{
|
||||
$name = $this->getNodeName();
|
||||
|
||||
$properties = array(
|
||||
'name' => $name,
|
||||
'operator' => $this->properties['operator'],
|
||||
);
|
||||
if (array_key_exists('childNames', $this->properties)) {
|
||||
$properties['child_names'] = $this->properties['childNames'];
|
||||
} else {
|
||||
$properties['child_names'] = array();
|
||||
}
|
||||
$node = new BpNode($config, (object) $properties);
|
||||
|
||||
foreach ($this->getProperties() as $key => $val) {
|
||||
if ($key === 'parentName') {
|
||||
$config->getBpNode($val)->addChild($node);
|
||||
continue;
|
||||
}
|
||||
$func = 'set' . ucfirst($key);
|
||||
$node->$func($val);
|
||||
}
|
||||
|
||||
$config->addNode($name, $node);
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
namespace Icinga\Module\Businessprocess\Modification;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
|
||||
class NodeModifyAction extends NodeAction
|
||||
{
|
||||
|
|
@ -10,11 +13,18 @@ class NodeModifyAction extends NodeAction
|
|||
|
||||
protected $preserveProperties = array('formerProperties', 'properties');
|
||||
|
||||
// Can be called multiple times
|
||||
public function setNodeProperties(Node $node, $properties)
|
||||
/**
|
||||
* Set properties for a specific node
|
||||
*
|
||||
* Can be called multiple times
|
||||
*
|
||||
* @param Node $node
|
||||
* @param array $properties
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setNodeProperties(Node $node, array $properties)
|
||||
{
|
||||
$old = array();
|
||||
|
||||
foreach (array_keys($properties) as $key) {
|
||||
|
||||
$this->properties[$key] = $properties[$key];
|
||||
|
|
@ -30,15 +40,18 @@ class NodeModifyAction extends NodeAction
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function appliesTo(BusinessProcess $bp)
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function appliesTo(BpConfig $config)
|
||||
{
|
||||
$name = $this->getNodeName();
|
||||
|
||||
if (! $bp->hasNode($name)) {
|
||||
if (! $config->hasNode($name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$node = $bp->getNode($name);
|
||||
$node = $config->getNode($name);
|
||||
|
||||
foreach ($this->properties as $key => $val) {
|
||||
$func = 'get' . ucfirst($key);
|
||||
|
|
@ -50,9 +63,12 @@ class NodeModifyAction extends NodeAction
|
|||
return true;
|
||||
}
|
||||
|
||||
public function applyTo(BusinessProcess $bp)
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function applyTo(BpConfig $config)
|
||||
{
|
||||
$node = $bp->getNode($this->getNodeName());
|
||||
$node = $config->getNode($this->getNodeName());
|
||||
|
||||
foreach ($this->properties as $key => $val) {
|
||||
$func = 'set' . ucfirst($key);
|
||||
|
|
@ -62,23 +78,37 @@ class NodeModifyAction extends NodeAction
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $properties
|
||||
* @return $this
|
||||
*/
|
||||
public function setProperties($properties)
|
||||
{
|
||||
$this->properties = $properties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $properties
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormerProperties($properties)
|
||||
{
|
||||
$this->formerProperties = $properties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFormerProperties()
|
||||
{
|
||||
return $this->formerProperties;
|
||||
67
library/Businessprocess/Modification/NodeRemoveAction.php
Normal file
67
library/Businessprocess/Modification/NodeRemoveAction.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Modification;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
|
||||
/**
|
||||
* NodeRemoveAction
|
||||
*
|
||||
* Tracks removed nodes
|
||||
*
|
||||
* @package Icinga\Module\Businessprocess
|
||||
*/
|
||||
class NodeRemoveAction extends NodeAction
|
||||
{
|
||||
protected $preserveProperties = array('parentName');
|
||||
|
||||
protected $parentName;
|
||||
|
||||
/**
|
||||
* @param $parentName
|
||||
* @return $this
|
||||
*/
|
||||
public function setParentName($parentName = null)
|
||||
{
|
||||
$this->parentName = $parentName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParentName()
|
||||
{
|
||||
return $this->parentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function appliesTo(BpConfig $config)
|
||||
{
|
||||
$parent = $this->getParentName();
|
||||
if ($parent === null) {
|
||||
return $config->hasNode($this->getNodeName());
|
||||
} else {
|
||||
return $config->hasNode($this->getNodeName()) && $config->hasNode($this->getParentName()) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function applyTo(BpConfig $config)
|
||||
{
|
||||
$parent = $this->getParentName();
|
||||
if ($parent === null) {
|
||||
$config->removeNode($this->getNodeName());
|
||||
} else {
|
||||
$node = $config->getNode($this->getNodeName());
|
||||
$node->removeParent($parent);
|
||||
if (! $node->hasParents()) {
|
||||
$config->removeNode($this->getNodeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
namespace Icinga\Module\Businessprocess\Modification;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Web\Session\SessionNamespace as Session;
|
||||
use Icinga\Module\Businessprocess\NodeAction;
|
||||
|
||||
class ProcessChanges
|
||||
{
|
||||
/** @var NodeAction[] */
|
||||
protected $changes = array();
|
||||
|
||||
/** @var Session */
|
||||
protected $session;
|
||||
|
||||
/** @var bool */
|
||||
protected $hasBeenModified = false;
|
||||
|
||||
/** @var string Session storage key for this processes changes */
|
||||
protected $sessionKey;
|
||||
|
||||
/**
|
||||
* ProcessChanges constructor.
|
||||
*
|
||||
* Direct access is not allowed
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function construct(BusinessProcess $bp, Session $session)
|
||||
/**
|
||||
* @param BpConfig $bp
|
||||
* @param Session $session
|
||||
*
|
||||
* @return ProcessChanges
|
||||
*/
|
||||
public static function construct(BpConfig $bp, Session $session)
|
||||
{
|
||||
$key = 'changes.' . $bp->getName();
|
||||
$changes = new ProcessChanges();
|
||||
|
|
@ -27,7 +43,7 @@ class ProcessChanges
|
|||
|
||||
if ($actions = $session->get($key)) {
|
||||
foreach ($actions as $string) {
|
||||
$changes->push(NodeAction::unserialize($string));
|
||||
$changes->push(NodeAction::unSerialize($string));
|
||||
}
|
||||
}
|
||||
$changes->session = $session;
|
||||
|
|
@ -35,6 +51,12 @@ class ProcessChanges
|
|||
return $changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
* @param $properties
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function modifyNode(Node $node, $properties)
|
||||
{
|
||||
$action = new NodeModifyAction($node);
|
||||
|
|
@ -42,6 +64,26 @@ class ProcessChanges
|
|||
return $this->push($action);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
* @param $properties
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addChildrenToNode($children, Node $node = null)
|
||||
{
|
||||
$action = new NodeAddChildrenAction($node);
|
||||
$action->setChildren($children);
|
||||
return $this->push($action);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node|string $nodeName
|
||||
* @param array $properties
|
||||
* @param Node $parent
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function createNode($nodeName, $properties, Node $parent = null)
|
||||
{
|
||||
$action = new NodeCreateAction($nodeName);
|
||||
|
|
@ -52,11 +94,29 @@ class ProcessChanges
|
|||
return $this->push($action);
|
||||
}
|
||||
|
||||
public function deleteNode(Node $node)
|
||||
/**
|
||||
* @param Node $node
|
||||
* @param array $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function deleteNode(Node $node, array $path = null)
|
||||
{
|
||||
return $this->push(new NodeDeleteAction($node));
|
||||
$action = new NodeRemoveAction($node);
|
||||
if ($path !== null) {
|
||||
$action->setPath($path);
|
||||
}
|
||||
|
||||
return $this->push($action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new action to the stack
|
||||
*
|
||||
* @param NodeAction $change
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function push(NodeAction $change)
|
||||
{
|
||||
$this->changes[] = $change;
|
||||
|
|
@ -64,11 +124,21 @@ class ProcessChanges
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all stacked actions
|
||||
*
|
||||
* @return NodeAction[]
|
||||
*/
|
||||
public function getChanges()
|
||||
{
|
||||
return $this->changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget all changes and remove them from the Session
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->hasBeenModified = true;
|
||||
|
|
@ -77,16 +147,31 @@ class ProcessChanges
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether there are no stacked changes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->count() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of stacked changes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first change on the stack, false if empty
|
||||
*
|
||||
* @return NodeAction|boolean
|
||||
*/
|
||||
public function shift()
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
|
|
@ -97,6 +182,11 @@ class ProcessChanges
|
|||
return array_shift($this->changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last change on the stack, false if empty
|
||||
*
|
||||
* @return NodeAction|boolean
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
|
|
@ -107,6 +197,11 @@ class ProcessChanges
|
|||
return array_pop($this->changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier used for this processes changes in our Session storage
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSessionKey()
|
||||
{
|
||||
return $this->sessionKey;
|
||||
|
|
@ -117,6 +212,9 @@ class ProcessChanges
|
|||
return $this->hasBeenModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
$serialized = array();
|
||||
|
|
@ -127,6 +225,9 @@ class ProcessChanges
|
|||
return $serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist to session on destruction
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (! $this->hasBeenModified()) {
|
||||
19
library/Businessprocess/MonitoredNode.php
Normal file
19
library/Businessprocess/MonitoredNode.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
|
||||
abstract class MonitoredNode extends Node
|
||||
{
|
||||
abstract public function getUrl();
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
if ($this->isMissing()) {
|
||||
return Link::create($this->getAlias(), '#');
|
||||
} else {
|
||||
return Link::create($this->getAlias(), $this->getUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,8 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Exception;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
|
||||
abstract class Node
|
||||
{
|
||||
|
|
@ -24,7 +22,7 @@ abstract class Node
|
|||
const ICINGA_UNREACHABLE = 2;
|
||||
const ICINGA_PENDING = 99;
|
||||
|
||||
protected static $sortStateToStateMap = array(
|
||||
protected $sortStateToStateMap = array(
|
||||
4 => self::ICINGA_CRITICAL,
|
||||
3 => self::ICINGA_UNKNOWN,
|
||||
2 => self::ICINGA_WARNING,
|
||||
|
|
@ -32,7 +30,7 @@ abstract class Node
|
|||
0 => self::ICINGA_OK
|
||||
);
|
||||
|
||||
protected static $stateToSortStateMap = array(
|
||||
protected $stateToSortStateMap = array(
|
||||
self::ICINGA_PENDING => 1,
|
||||
self::ICINGA_UNKNOWN => 3,
|
||||
self::ICINGA_CRITICAL => 4,
|
||||
|
|
@ -43,7 +41,7 @@ abstract class Node
|
|||
/**
|
||||
* Main business process object
|
||||
*
|
||||
* @var BusinessProcess
|
||||
* @var BpConfig
|
||||
*/
|
||||
protected $bp;
|
||||
|
||||
|
|
@ -96,7 +94,7 @@ abstract class Node
|
|||
|
||||
protected $className = 'unknown';
|
||||
|
||||
protected static $state_names = array(
|
||||
protected $stateNames = array(
|
||||
'OK',
|
||||
'WARNING',
|
||||
'CRITICAL',
|
||||
|
|
@ -104,7 +102,7 @@ abstract class Node
|
|||
99 => 'PENDING'
|
||||
);
|
||||
|
||||
abstract public function __construct(BusinessProcess $bp, $object);
|
||||
abstract public function __construct(BpConfig $bp, $object);
|
||||
|
||||
public function setMissing($missing = true)
|
||||
{
|
||||
|
|
@ -127,32 +125,38 @@ abstract class Node
|
|||
return $this->missing;
|
||||
}
|
||||
|
||||
public function hasMissingChildren()
|
||||
{
|
||||
return count($this->getMissingChildren()) > 0;
|
||||
}
|
||||
|
||||
public function getMissingChildren()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function hasInfoUrl()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addChild(Node $node)
|
||||
{
|
||||
if (array_key_exists((string) $node, $this->children)) {
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'Node "%s" has been defined more than once',
|
||||
$node
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->childs[(string) $node] = $node;
|
||||
$node->addParent($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setState($state)
|
||||
{
|
||||
$this->state = (int) $state;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget my state
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function clearState()
|
||||
{
|
||||
$this->state = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAck($ack = true)
|
||||
{
|
||||
$this->ack = $ack;
|
||||
|
|
@ -165,9 +169,19 @@ abstract class Node
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getStateName()
|
||||
public function getStateName($state = null)
|
||||
{
|
||||
return static::$state_names[ $this->getState() ];
|
||||
$states = $this->enumStateNames();
|
||||
if ($state === null) {
|
||||
return $states[ $this->getState() ];
|
||||
} else {
|
||||
return $states[ $state ];
|
||||
}
|
||||
}
|
||||
|
||||
public function enumStateNames()
|
||||
{
|
||||
return $this->stateNames;
|
||||
}
|
||||
|
||||
public function getState()
|
||||
|
|
@ -180,6 +194,7 @@ abstract class Node
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
|
|
@ -238,16 +253,6 @@ abstract class Node
|
|||
return $this->ack;
|
||||
}
|
||||
|
||||
public function isSimulationMode()
|
||||
{
|
||||
return $this->bp->isSimulationMode();
|
||||
}
|
||||
|
||||
public function isEditMode()
|
||||
{
|
||||
return $this->bp->isEditMode();
|
||||
}
|
||||
|
||||
public function getChildren($filter = null)
|
||||
{
|
||||
return array();
|
||||
|
|
@ -283,158 +288,90 @@ abstract class Node
|
|||
return count($this->parents) > 0;
|
||||
}
|
||||
|
||||
protected function stateToSortState($state)
|
||||
public function hasParentName($name)
|
||||
{
|
||||
if (array_key_exists($state, static::$stateToSortStateMap)) {
|
||||
return static::$stateToSortStateMap[$state];
|
||||
foreach ($this->getParents() as $parent) {
|
||||
if ($parent->getName() === $name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ProgrammingError('Got invalid state %s', $sort_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
public function removeParent($name)
|
||||
{
|
||||
$this->parents = array_filter(
|
||||
$this->parents,
|
||||
function (BpNode $parent) use ($name) {
|
||||
return $parent->getName() !== $name;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getParents()
|
||||
{
|
||||
return $this->parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPaths()
|
||||
{
|
||||
if ($this->bp->hasRootNode($this->getName())) {
|
||||
return array(array($this->getName()));
|
||||
}
|
||||
|
||||
$paths = array();
|
||||
foreach ($this->parents as $parent) {
|
||||
foreach ($parent->getPaths() as $path) {
|
||||
// $path[] = $this->getName();
|
||||
$paths[] = $path;
|
||||
}
|
||||
|
||||
}
|
||||
// TODO! -> for delete etc
|
||||
return $paths;
|
||||
}
|
||||
|
||||
protected function stateToSortState($state)
|
||||
{
|
||||
if (array_key_exists($state, $this->stateToSortStateMap)) {
|
||||
return $this->stateToSortStateMap[$state];
|
||||
}
|
||||
|
||||
throw new ProgrammingError(
|
||||
'Got invalid state for node %s: %s',
|
||||
$this->getName(),
|
||||
var_export($state, 1) . var_export($this->stateToSortStateMap, 1)
|
||||
);
|
||||
}
|
||||
|
||||
protected function sortStateTostate($sortState)
|
||||
{
|
||||
$sortState = $sortState >> self::SHIFT_FLAGS;
|
||||
|
||||
if (array_key_exists($sortState, static::$sortStateToStateMap)) {
|
||||
return static::$sortStateToStateMap[$sortState];
|
||||
if (array_key_exists($sortState, $this->sortStateToStateMap)) {
|
||||
return $this->sortStateToStateMap[$sortState];
|
||||
}
|
||||
|
||||
throw new ProgrammingError('Got invalid sorting state %s', $sort_state);
|
||||
throw new ProgrammingError('Got invalid sorting state %s', $sortState);
|
||||
}
|
||||
|
||||
protected function renderHtmlForChildren($view)
|
||||
{
|
||||
$html = '';
|
||||
if ($this->hasChildren()) {
|
||||
foreach ($this->getChildren() as $name => $child) {
|
||||
$html .= '<tr><td>'
|
||||
. $child->renderHtml($view)
|
||||
. '</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
protected function getId($prefix = '')
|
||||
{
|
||||
return md5($prefix . (string) $this);
|
||||
}
|
||||
|
||||
protected function getObjectClassName()
|
||||
public function getObjectClassName()
|
||||
{
|
||||
return $this->className;
|
||||
}
|
||||
|
||||
protected function getStateClassNames()
|
||||
/**
|
||||
* @return Link
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
$state = strtolower($this->getStateName());
|
||||
|
||||
if ($this->isMissing()) {
|
||||
return array('missing');
|
||||
} elseif ($state === 'ok') {
|
||||
return array('ok');
|
||||
} else {
|
||||
return array('problem', $state);
|
||||
}
|
||||
}
|
||||
|
||||
public function renderHtml($view, $prefix = '')
|
||||
{
|
||||
$id = $this->getId($prefix);
|
||||
$handled = $this->isAcknowledged() || $this->isInDowntime();
|
||||
|
||||
$html = sprintf(
|
||||
'<table class="bp %s%s%s%s" id="%s"><tbody><tr>',
|
||||
implode(' ', $this->getStateClassNames()),
|
||||
$handled ? ' handled' : '',
|
||||
($this->hasChildren() ? ' operator ' : ' node '),
|
||||
$this->getObjectClassName(),
|
||||
$id
|
||||
);
|
||||
|
||||
if ($this->hasChildren()) {
|
||||
$html .= sprintf(
|
||||
'<th%s><span class="op">%s</span></th>',
|
||||
sprintf(' rowspan="%d"', $this->countChildren() + 1),
|
||||
$this->operatorHtml()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$title = preg_replace(
|
||||
'~(</a>)~',
|
||||
implode('', $this->getIcons($view)) . '$1',
|
||||
$this->renderLink($view)
|
||||
);
|
||||
|
||||
$title = preg_replace('#</a>#', ' ' . $view->timeSince($this->getLastStateChange()) . '</a>', $title);
|
||||
$icons = array();
|
||||
|
||||
foreach ($this->getActionIcons($view) as $icon) {
|
||||
$icons[] = $icon;
|
||||
}
|
||||
|
||||
if ($this->hasInfoUrl()) {
|
||||
$url = $this->getInfoUrl();
|
||||
$icons[] = $this->actionIcon(
|
||||
$view,
|
||||
'help',
|
||||
$url,
|
||||
sprintf('%s: %s', mt('businessprocess', 'More information'), $url)
|
||||
);
|
||||
}
|
||||
$title = implode("\n", $icons) . $title;
|
||||
|
||||
$html .= sprintf(
|
||||
'<td>%s</td></tr>',
|
||||
$title
|
||||
);
|
||||
foreach ($this->getChildren() as $name => $child) {
|
||||
$html .= '<tr><td>' . $child->renderHtml($view, $id . '-') . '</td></tr>';
|
||||
}
|
||||
$html .= "</tbody></table>\n";
|
||||
return $html;
|
||||
}
|
||||
|
||||
protected function getActionIcons($view)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function actionIcon($view, $icon, $url, $title)
|
||||
{
|
||||
if ($url instanceof Url || ! preg_match('~^https?://~', $url)) {
|
||||
$target = '';
|
||||
} else {
|
||||
$target = ' target="_blank"';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
' <a href="%s" %stitle="%s" style="float: right" data-base-target="bp-overlay">%s</a>',
|
||||
$url,
|
||||
$target,
|
||||
$view->escape($title),
|
||||
$view->icon($icon)
|
||||
);
|
||||
}
|
||||
|
||||
public function renderLink($view)
|
||||
{
|
||||
return '<a href="#">' . ($this->hasAlias() ? $this->getAlias() : $this->name) . '</a>';
|
||||
}
|
||||
|
||||
public function getIcons($view)
|
||||
{
|
||||
$icons = array();
|
||||
if ($this->isInDowntime()) {
|
||||
$icons[] = $view->icon('moon');
|
||||
}
|
||||
if ($this->isAcknowledged()) {
|
||||
$icons[] = $view->icon('ok');
|
||||
}
|
||||
return $icons;
|
||||
return Link::create($this->getAlias(), '#');
|
||||
}
|
||||
|
||||
public function operatorHtml()
|
||||
|
|
@ -442,16 +379,18 @@ abstract class Node
|
|||
return ' ';
|
||||
}
|
||||
|
||||
public function toLegacyConfigString(& $rendered = array()) { return '';}
|
||||
//abstract public function toLegacyConfigString();
|
||||
|
||||
public function __toString()
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->parents = array();
|
||||
unset($this->parents);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
abstract class NodeAction
|
||||
{
|
||||
const TYPE_CREATE = 'create';
|
||||
|
||||
const TYPE_REMOVE = 'remove';
|
||||
|
||||
const TYPE_MODIFY = 'modify';
|
||||
|
||||
const TYPE_CHILD_ADD = 'childRemove';
|
||||
|
||||
const TYPE_CHILD_REMOVE = 'childAdd';
|
||||
|
||||
protected $nodeName;
|
||||
|
||||
protected $actionName;
|
||||
|
||||
protected $preserveProperties = array();
|
||||
|
||||
public function __construct($node)
|
||||
{
|
||||
$this->nodeName = (string) $node;
|
||||
}
|
||||
|
||||
abstract public function applyTo(BusinessProcess $bp);
|
||||
|
||||
public function getNodeName()
|
||||
{
|
||||
return $this->nodeName;
|
||||
}
|
||||
|
||||
public function is($actionName)
|
||||
{
|
||||
return $this->getActionName() === $actionName;
|
||||
}
|
||||
|
||||
public static function create($actionName, $nodeName)
|
||||
{
|
||||
$classname = __NAMESPACE__ . '\\Node' . ucfirst($actionName) . 'Action';
|
||||
$object = new $classname($nodeName);
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
$object = (object) array(
|
||||
'actionName' => $this->getActionName(),
|
||||
'nodeName' => $this->getNodeName(),
|
||||
'properties' => array()
|
||||
);
|
||||
|
||||
foreach ($this->preserveProperties as $key) {
|
||||
$func = 'get' . ucfirst($key);
|
||||
$object->properties[$key] = $this->$func();
|
||||
}
|
||||
|
||||
return json_encode($object);
|
||||
}
|
||||
|
||||
public static function unserialize($string)
|
||||
{
|
||||
$object = json_decode($string);
|
||||
$action = self::create($object->actionName, $object->nodeName);
|
||||
|
||||
foreach ($object->properties as $key => $val) {
|
||||
$func = 'set' . ucfirst($key);
|
||||
$action->$func($val);
|
||||
}
|
||||
|
||||
return $action;
|
||||
}
|
||||
|
||||
public function getActionName()
|
||||
{
|
||||
if ($this->actionName === null) {
|
||||
if (! preg_match('/\\\Node(\w+)Action$/', get_class($this), $m)) {
|
||||
throw new ProgrammingError(
|
||||
'"%s" is not a NodeAction class',
|
||||
get_class($this)
|
||||
);
|
||||
}
|
||||
$this->actionName = lcfirst($m[1]);
|
||||
}
|
||||
|
||||
return $this->actionName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
class NodeCreateAction extends NodeAction
|
||||
{
|
||||
protected $parentName;
|
||||
|
||||
protected $properties = array();
|
||||
|
||||
protected $preserveProperties = array('parentName', 'properties');
|
||||
|
||||
public function setParent(Node $name)
|
||||
{
|
||||
$this->parentName = $name;
|
||||
}
|
||||
|
||||
public function hasParent()
|
||||
{
|
||||
return $this->parentName !== null;
|
||||
}
|
||||
|
||||
public function getParentName()
|
||||
{
|
||||
return $this->parentName;
|
||||
}
|
||||
|
||||
public function setParentName($name)
|
||||
{
|
||||
$this->parentName = $name;
|
||||
}
|
||||
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
public function setProperties($properties)
|
||||
{
|
||||
$this->properties = $properties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function appliesTo(BusinessProcess $bp)
|
||||
{
|
||||
return ! $bp->hasNode($this->getNodeName());
|
||||
}
|
||||
|
||||
public function applyTo(BusinessProcess $bp)
|
||||
{
|
||||
$node = new BpNode($bp, (object) array(
|
||||
'name' => $this->getNodeName(),
|
||||
'operator' => $this->properties->operator,
|
||||
'child_names' => $this->properties->childNames
|
||||
));
|
||||
|
||||
foreach ($this->properties as $key => $val) {
|
||||
$func = 'set' . ucfirst($key);
|
||||
$node->$func($val);
|
||||
}
|
||||
|
||||
$bp->addNode($this->getNodeName(), $node);
|
||||
if ($this->hasParent()) {
|
||||
$node->addParent($bp->getNode($this->getParentName()));
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
class NodeRemoveAction extends NodeAction
|
||||
{
|
||||
public function appliesTo(BusinessProcess $bp)
|
||||
{
|
||||
return $bp->hasNode($this->getNodeName());
|
||||
}
|
||||
|
||||
public function applyTo(BusinessProcess $bp)
|
||||
{
|
||||
$bp->removeNode($this->getNodeName());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\ProvidedHook\Monitoring;
|
||||
|
||||
use Icinga\Module\Monitoring\Hook\HostActionsHook;
|
||||
use Icinga\Module\Monitoring\Object\Host;
|
||||
|
||||
class HostActions extends HostActionsHook
|
||||
{
|
||||
public function getActionsForHost(Host $host)
|
||||
{
|
||||
$label = mt('businessprocess', 'Business Impact');
|
||||
return array(
|
||||
$label => 'businessprocess/node/impact?name='
|
||||
. rawurlencode($host->getName() . ';Hoststatus')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\ProvidedHook\Monitoring;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Monitoring\Hook\ServiceActionsHook;
|
||||
use Icinga\Module\Monitoring\Object\Service;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
class ServiceActions extends ServiceActionsHook
|
||||
{
|
||||
public function getActionsForService(Service $service)
|
||||
{
|
||||
$label = mt('businessprocess', 'Business Impact');
|
||||
return array(
|
||||
$label => sprintf(
|
||||
'businessprocess/node/impact?name=%s',
|
||||
rawurlencode(
|
||||
sprintf('%s;%s', $service->getHost()->getName(), $service->getName())
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
66
library/Businessprocess/Renderer/Breadcrumb.php
Normal file
66
library/Businessprocess/Renderer/Breadcrumb.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
use Icinga\Module\Businessprocess\Html\Element;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer\NodeTile;
|
||||
|
||||
class Breadcrumb extends BaseElement
|
||||
{
|
||||
protected $tag = 'ul';
|
||||
|
||||
protected $defaultAttributes = array(
|
||||
'class' => 'breadcrumb',
|
||||
'data-base-target' => '_main'
|
||||
);
|
||||
|
||||
/**
|
||||
* @param Renderer $renderer
|
||||
* @return static
|
||||
*/
|
||||
public static function create(Renderer $renderer)
|
||||
{
|
||||
$bp = $renderer->getBusinessProcess();
|
||||
$breadcrumb = new static;
|
||||
$bpUrl = $renderer->getBaseUrl();
|
||||
if ($bpUrl->getParam('action') === 'delete') {
|
||||
$bpUrl->remove('action');
|
||||
}
|
||||
$breadcrumb->add(Element::create('li')->add(
|
||||
Link::create($bp->getTitle(), $bpUrl)
|
||||
));
|
||||
$path = $renderer->getCurrentPath();
|
||||
|
||||
$parts = array();
|
||||
while ($node = array_pop($path)) {
|
||||
array_unshift(
|
||||
$parts,
|
||||
static::renderNode($bp->getNode($node), $path, $renderer)
|
||||
);
|
||||
}
|
||||
$breadcrumb->addContent($parts);
|
||||
|
||||
return $breadcrumb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @param array $path
|
||||
* @param Renderer $renderer
|
||||
*
|
||||
* @return NodeTile
|
||||
*/
|
||||
protected static function renderNode(BpNode $node, $path, Renderer $renderer)
|
||||
{
|
||||
// TODO: something more generic than NodeTile?
|
||||
$renderer = clone($renderer);
|
||||
$renderer->lock()->setIsBreadcrumb();
|
||||
$p = new NodeTile($renderer, (string) $node, $node, $path);
|
||||
$p->attributes()->add('class', $renderer->getNodeClasses($node));
|
||||
$p->setTag('li');
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
328
library/Businessprocess/Renderer/Renderer.php
Normal file
328
library/Businessprocess/Renderer/Renderer.php
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer;
|
||||
|
||||
use Icinga\Date\DateFormatter;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
use Icinga\Module\Businessprocess\Html\Element;
|
||||
use Icinga\Module\Businessprocess\Html\Html;
|
||||
use Icinga\Module\Businessprocess\Html\HtmlString;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
||||
abstract class Renderer extends Html
|
||||
{
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var BpNode */
|
||||
protected $parent;
|
||||
|
||||
/** @var bool Administrative actions are hidden unless unlocked */
|
||||
protected $locked = true;
|
||||
|
||||
/** @var Url */
|
||||
protected $url;
|
||||
|
||||
/** @var Url */
|
||||
protected $baseUrl;
|
||||
|
||||
/** @var array */
|
||||
protected $path = array();
|
||||
|
||||
/** @var bool */
|
||||
protected $isBreadcrumb = false;
|
||||
|
||||
/**
|
||||
* Renderer constructor.
|
||||
*
|
||||
* @param BpConfig $config
|
||||
* @param BpNode|null $parent
|
||||
*/
|
||||
public function __construct(BpConfig $config, BpNode $parent = null)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpConfig
|
||||
*/
|
||||
public function getBusinessProcess()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this will render all root nodes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function wantsRootNodes()
|
||||
{
|
||||
return $this->parent === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this will only render parts of given config
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rendersSubNode()
|
||||
{
|
||||
return $this->parent !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode
|
||||
*/
|
||||
public function getParentNode()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getParentNodes()
|
||||
{
|
||||
if ($this->wantsRootNodes()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->parent->getParents();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getChildNodes()
|
||||
{
|
||||
if ($this->wantsRootNodes()) {
|
||||
return $this->config->getRootNodes();
|
||||
} else {
|
||||
return $this->parent->getChildren();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function countChildNodes()
|
||||
{
|
||||
if ($this->wantsRootNodes()) {
|
||||
return $this->config->countChildren();
|
||||
} else {
|
||||
return $this->parent->countChildren();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $summary
|
||||
* @return Container
|
||||
*/
|
||||
public function renderStateBadges($summary)
|
||||
{
|
||||
$container = Container::create(
|
||||
array('class' => 'badges')
|
||||
)/* ->renderIfEmpty(false) */;
|
||||
|
||||
foreach ($summary as $state => $cnt) {
|
||||
if ($cnt === 0
|
||||
|| $state === 'OK'
|
||||
|| $state === 'UP'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$container->addContent(
|
||||
Element::create(
|
||||
'span',
|
||||
array(
|
||||
'class' => array(
|
||||
'badge',
|
||||
'badge-' . strtolower($state)
|
||||
),
|
||||
// TODO: We should translate this in this module
|
||||
'title' => mt('monitoring', $state)
|
||||
)
|
||||
)->setContent($cnt)
|
||||
);
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
public function getNodeClasses(Node $node)
|
||||
{
|
||||
$classes = array(
|
||||
strtolower($node->getStateName())
|
||||
);
|
||||
|
||||
if ($node->isHandled()) {
|
||||
$classes[] = 'handled';
|
||||
}
|
||||
|
||||
if ($node instanceof BpNode) {
|
||||
$classes[] = 'process-node';
|
||||
} else {
|
||||
$classes[] = 'monitored-node';
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
public function setPath(array $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getCurrentPath()
|
||||
{
|
||||
$path = $this->getPath();
|
||||
if ($this->rendersSubNode()) {
|
||||
$path[] = (string) $this->parent;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Url $url
|
||||
* @return $this
|
||||
*/
|
||||
public function setUrl(Url $url)
|
||||
{
|
||||
$this->url = $url->without(array(
|
||||
'deletenode',
|
||||
'deleteparent',
|
||||
'editnode',
|
||||
'simulationnode'
|
||||
));
|
||||
$this->setBaseUrl($url);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Url $url
|
||||
* @return $this
|
||||
*/
|
||||
public function setBaseUrl(Url $url)
|
||||
{
|
||||
$this->baseUrl = $url->without(array('node', 'path'));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Url
|
||||
* @throws ProgrammingError
|
||||
*/
|
||||
public function getBaseUrl()
|
||||
{
|
||||
if ($this->baseUrl === null) {
|
||||
throw new ProgrammingError('Renderer has no baseUrl');
|
||||
}
|
||||
|
||||
return clone($this->baseUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isLocked()
|
||||
{
|
||||
return $this->locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function lock()
|
||||
{
|
||||
$this->locked = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function unlock()
|
||||
{
|
||||
$this->locked = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Get rid of this
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsBreadcrumb()
|
||||
{
|
||||
$this->isBreadcrumb = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isBreadcrumb()
|
||||
{
|
||||
return $this->isBreadcrumb;
|
||||
}
|
||||
|
||||
public function timeSince($time, $timeOnly = false)
|
||||
{
|
||||
if (! $time) {
|
||||
return HtmlString::create('');
|
||||
}
|
||||
|
||||
return Element::create(
|
||||
'span',
|
||||
array(
|
||||
'class' => array('relative-time', 'time-since'),
|
||||
'title' => DateFormatter::formatDateTime($time),
|
||||
)
|
||||
)->setContent(DateFormatter::timeSince($time, $timeOnly));
|
||||
}
|
||||
|
||||
protected function createUnboundParent(BpConfig $bp)
|
||||
{
|
||||
$unbound = $bp->getUnboundNodes();
|
||||
|
||||
$parent = new BpNode($bp, (object) array(
|
||||
'name' => '__unbound__',
|
||||
'operator' => '|',
|
||||
'child_names' => array_keys($unbound)
|
||||
));
|
||||
$parent->getState();
|
||||
$parent->setMissing()
|
||||
->setDowntime(false)
|
||||
->setAck(false)
|
||||
->setAlias('Unbound nodes');
|
||||
|
||||
return $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just to be on the safe side
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
unset($this->parent);
|
||||
unset($this->config);
|
||||
}
|
||||
}
|
||||
113
library/Businessprocess/Renderer/TileRenderer.php
Normal file
113
library/Businessprocess/Renderer/TileRenderer.php
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer;
|
||||
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
use Icinga\Module\Businessprocess\Html\Icon;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer\NodeTile;
|
||||
|
||||
class TileRenderer extends Renderer
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$bp = $this->config;
|
||||
$nodesDiv = Container::create(
|
||||
array(
|
||||
'class' => array(
|
||||
'tiles',
|
||||
$this->howMany()
|
||||
),
|
||||
'data-base-target' => '_self',
|
||||
)
|
||||
);
|
||||
|
||||
$nodes = $this->getChildNodes();
|
||||
|
||||
if (! $this->isLocked() && count($nodes) > 8) {
|
||||
$this->add($this->addNewNode());
|
||||
}
|
||||
|
||||
$path = $this->getCurrentPath();
|
||||
foreach ($nodes as $name => $node) {
|
||||
$this->add(new NodeTile($this, $name, $node, $path));
|
||||
}
|
||||
|
||||
if ($this->wantsRootNodes()) {
|
||||
$unbound = $this->createUnboundParent($bp);
|
||||
if ($unbound->hasChildren()) {
|
||||
$name = $unbound->getAlias();
|
||||
$this->add(new NodeTile($this, $name, $unbound));
|
||||
}
|
||||
}
|
||||
|
||||
if (! $this->isLocked()) {
|
||||
$this->add($this->addNewNode());
|
||||
}
|
||||
|
||||
$nodesDiv->addContent($this->getContent());
|
||||
$this->setContent($nodesDiv);
|
||||
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/**
|
||||
* A CSS class giving a rough indication of how many nodes we have
|
||||
*
|
||||
* This is used to show larger tiles when there are few and smaller
|
||||
* ones if there are many.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function howMany()
|
||||
{
|
||||
$count = $this->countChildNodes();
|
||||
$howMany = 'normal';
|
||||
|
||||
if ($count <= 6) {
|
||||
$howMany = 'few';
|
||||
} elseif ($count > 12) {
|
||||
$howMany = 'many';
|
||||
}
|
||||
|
||||
return $howMany;
|
||||
}
|
||||
|
||||
protected function addNewNode()
|
||||
{
|
||||
$div = Container::create(
|
||||
array('class' => 'addnew')
|
||||
);
|
||||
|
||||
$actions = Container::create(
|
||||
array(
|
||||
'class' => 'actions',
|
||||
'data-base-target' => '_self'
|
||||
)
|
||||
);
|
||||
|
||||
$link = Link::create(
|
||||
$this->translate('Add'),
|
||||
$this->getUrl()->with('action', 'add'),
|
||||
null,
|
||||
array(
|
||||
'title' => $this->translate('Add a new business process node')
|
||||
)
|
||||
);
|
||||
$actions->add(
|
||||
Link::create(
|
||||
Icon::create('plus'),
|
||||
$this->getUrl()->with('action', 'add'),
|
||||
null,
|
||||
array(
|
||||
'title' => $this->translate('Add a new business process node')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return $div->add($actions)->add($link);
|
||||
}
|
||||
}
|
||||
279
library/Businessprocess/Renderer/TileRenderer/NodeTile.php
Normal file
279
library/Businessprocess/Renderer/TileRenderer/NodeTile.php
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\HostNode;
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
use Icinga\Module\Businessprocess\Html\HtmlString;
|
||||
use Icinga\Module\Businessprocess\Html\Icon;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\ImportedNode;
|
||||
use Icinga\Module\Businessprocess\MonitoredNode;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\Renderer\Renderer;
|
||||
use Icinga\Module\Businessprocess\ServiceNode;
|
||||
|
||||
class NodeTile extends BaseElement
|
||||
{
|
||||
protected $tag = 'div';
|
||||
|
||||
protected $renderer;
|
||||
|
||||
protected $name;
|
||||
|
||||
protected $node;
|
||||
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var Container
|
||||
*/
|
||||
private $actions;
|
||||
|
||||
/**
|
||||
* NodeTile constructor.
|
||||
* @param Renderer $renderer
|
||||
* @param $name
|
||||
* @param Node $node
|
||||
* @param null $path
|
||||
*/
|
||||
public function __construct(Renderer $renderer, $name, Node $node, $path = null)
|
||||
{
|
||||
$this->renderer = $renderer;
|
||||
$this->name = $name;
|
||||
$this->node = $node;
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
protected function actions()
|
||||
{
|
||||
if ($this->actions === null) {
|
||||
$this->addActions();
|
||||
}
|
||||
return $this->actions;
|
||||
}
|
||||
|
||||
protected function addActions()
|
||||
{
|
||||
$this->actions = Container::create(
|
||||
array(
|
||||
'class' => 'actions',
|
||||
'data-base-target' => '_self'
|
||||
)
|
||||
);
|
||||
|
||||
return $this->add($this->actions);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$renderer = $this->renderer;
|
||||
$node = $this->node;
|
||||
|
||||
$attributes = $this->attributes();
|
||||
$attributes->add('class', $renderer->getNodeClasses($node));
|
||||
$attributes->add('id', 'bp-' . (string) $node);
|
||||
|
||||
$this->addActions();
|
||||
|
||||
$link = $this->getMainNodeLink();
|
||||
$this->add($link);
|
||||
|
||||
if ($node instanceof BpNode) {
|
||||
if ($renderer->isBreadcrumb()) {
|
||||
$link->addContent($renderer->renderStateBadges($node->getStateSummary()));
|
||||
} else {
|
||||
$this->addContent($renderer->renderStateBadges($node->getStateSummary()));
|
||||
}
|
||||
}
|
||||
|
||||
if (! $renderer->isBreadcrumb()) {
|
||||
$this->addDetailsActions();
|
||||
}
|
||||
|
||||
if (! $renderer->isLocked()) {
|
||||
$this->addActionLinks();
|
||||
}
|
||||
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
protected function getMainNodeUrl(Node $node)
|
||||
{
|
||||
if ($node instanceof BpNode) {
|
||||
return $this->makeBpUrl($node);
|
||||
} else {
|
||||
/** @var MonitoredNode $node */
|
||||
return $node->getUrl();
|
||||
}
|
||||
}
|
||||
|
||||
protected function buildBaseNodeUrl(Node $node)
|
||||
{
|
||||
$path = $this->path;
|
||||
$name = $this->name; // TODO: ??
|
||||
$renderer = $this->renderer;
|
||||
|
||||
$bp = $renderer->getBusinessProcess();
|
||||
$params = array(
|
||||
'config' => $node instanceof ImportedNode ?
|
||||
$node->getConfigName() :
|
||||
$bp->getName()
|
||||
);
|
||||
|
||||
if ($name !== null) {
|
||||
$params['node'] = $name;
|
||||
}
|
||||
|
||||
$url = $renderer->getBaseUrl();
|
||||
$p = $url->getParams();
|
||||
$p->mergeValues($params);
|
||||
if (! empty($path)) {
|
||||
$p->addValues('path', $path);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
protected function makeBpUrl(BpNode $node)
|
||||
{
|
||||
return $this->buildBaseNodeUrl($node);
|
||||
}
|
||||
|
||||
protected function makeMonitoredNodeUrl(MonitoredNode $node)
|
||||
{
|
||||
$path = $this->path;
|
||||
$name = $this->name; // TODO: ??
|
||||
$renderer = $this->renderer;
|
||||
|
||||
$bp = $renderer->getBusinessProcess();
|
||||
$params = array(
|
||||
'config' => $bp->getName()
|
||||
);
|
||||
|
||||
if ($name !== null) {
|
||||
$params['node'] = $node->getName();
|
||||
}
|
||||
|
||||
$url = $renderer->getBaseUrl();
|
||||
$p = $url->getParams();
|
||||
$p->mergeValues($params);
|
||||
if (! empty($path)) {
|
||||
$p->addValues('path', $path);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Link
|
||||
*/
|
||||
protected function getMainNodeLink()
|
||||
{
|
||||
$node = $this->node;
|
||||
$url = $this->getMainNodeUrl($node);
|
||||
if ($node instanceof ServiceNode) {
|
||||
$link = Link::create(
|
||||
$node->getAlias(),
|
||||
$url,
|
||||
null,
|
||||
array('data-base-target' => '_next')
|
||||
);
|
||||
} elseif ($node instanceof HostNode) {
|
||||
$link = Link::create(
|
||||
$node->getHostname(),
|
||||
$url,
|
||||
null,
|
||||
array('data-base-target' => '_next')
|
||||
);
|
||||
} else {
|
||||
$link = Link::create($node->getAlias(), $url);
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
protected function addDetailsActions()
|
||||
{
|
||||
$node = $this->node;
|
||||
$url = $this->getMainNodeUrl($node);
|
||||
|
||||
if ($node instanceof BpNode) {
|
||||
$this->actions()->add(Link::create(
|
||||
Icon::create('dashboard'),
|
||||
$url->with('mode', 'tile'),
|
||||
null,
|
||||
array(
|
||||
'title' => $this->translate('Show tiles for this subtree'),
|
||||
'data-base-target' => '_next'
|
||||
)
|
||||
))->add(Link::create(
|
||||
Icon::create('sitemap'),
|
||||
$url->with('mode', 'tree'),
|
||||
null,
|
||||
array(
|
||||
'title' => $this->translate('Show this subtree as a tree'),
|
||||
'data-base-target' => '_next'
|
||||
)
|
||||
));
|
||||
} else {
|
||||
// $url = $this->makeMonitoredNodeUrl($node);
|
||||
if ($node instanceof ServiceNode) {
|
||||
$this->actions()->add(Link::create(
|
||||
Icon::create('service'),
|
||||
$node->getUrl(),
|
||||
null,
|
||||
array('data-base-target' => '_next')
|
||||
));
|
||||
|
||||
} elseif ($node instanceof HostNode) {
|
||||
$this->actions()->add(Link::create(
|
||||
Icon::create('host'),
|
||||
$node->getUrl(),
|
||||
null,
|
||||
array('data-base-target' => '_next')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function addActionLinks()
|
||||
{
|
||||
$node = $this->node;
|
||||
$renderer = $this->renderer;
|
||||
|
||||
if ($node instanceof BpNode) {
|
||||
$this->actions()->add(Link::create(
|
||||
Icon::create('edit'),
|
||||
$renderer->getUrl()->with('action', 'edit')->with('editnode', $node->getName()),
|
||||
null,
|
||||
array('title' => $this->translate('Modify this business process node'))
|
||||
));
|
||||
} elseif ($node instanceof MonitoredNode) {
|
||||
$this->actions()->add(Link::create(
|
||||
Icon::create('magic'),
|
||||
$renderer->getUrl()->with('action', 'simulation')
|
||||
->with('simulationnode', $this->name),
|
||||
null,
|
||||
array('title' => $this->translate(
|
||||
'Show the business impact of this node by simulating a specific state'
|
||||
))
|
||||
));
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'action' => 'delete',
|
||||
'deletenode' => $node->getName(),
|
||||
);
|
||||
|
||||
$this->actions()->add(Link::create(
|
||||
Icon::create('cancel'),
|
||||
$renderer->getUrl()->with($params),
|
||||
null,
|
||||
array('title' => $this->translate('Delete this node'))
|
||||
));
|
||||
}
|
||||
}
|
||||
250
library/Businessprocess/Renderer/TreeRenderer.php
Normal file
250
library/Businessprocess/Renderer/TreeRenderer.php
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
use Icinga\Module\Businessprocess\Html\Element;
|
||||
use Icinga\Module\Businessprocess\Html\Icon;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
||||
class TreeRenderer extends Renderer
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$bp = $this->config;
|
||||
$this->add(Container::create(
|
||||
array(
|
||||
'id' => $bp->getHtmlId(),
|
||||
'class' => 'bp'
|
||||
),
|
||||
$this->renderBp($bp)
|
||||
));
|
||||
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpConfig $bp
|
||||
* @return string
|
||||
*/
|
||||
public function renderBp(BpConfig $bp)
|
||||
{
|
||||
$html = array();
|
||||
if ($this->wantsRootNodes()) {
|
||||
$nodes = $bp->getChildren();
|
||||
} else {
|
||||
$nodes = $this->parent->getChildren();
|
||||
}
|
||||
|
||||
foreach ($nodes as $name => $node) {
|
||||
$html[] = $this->renderNode($bp, $node);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
protected function getId(Node $node, $path)
|
||||
{
|
||||
return md5(implode(';', $path) . (string) $node);
|
||||
}
|
||||
|
||||
protected function getStateClassNames(Node $node)
|
||||
{
|
||||
$state = strtolower($node->getStateName());
|
||||
|
||||
if ($node->isMissing()) {
|
||||
return array('missing');
|
||||
} elseif ($state === 'ok') {
|
||||
if ($node->hasMissingChildren()) {
|
||||
return array('ok', 'missing-children');
|
||||
} else {
|
||||
return array('ok');
|
||||
}
|
||||
} else {
|
||||
return array('problem', $state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
* @return Icon[]
|
||||
*/
|
||||
public function getNodeIcons(Node $node)
|
||||
{
|
||||
$icons = array();
|
||||
if ($node->isInDowntime()) {
|
||||
$icons[] = Icon::create('moon');
|
||||
}
|
||||
if ($node->isAcknowledged()) {
|
||||
$icons[] = Icon::create('ok');
|
||||
}
|
||||
return $icons;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpConfig $bp
|
||||
* @param Node $node
|
||||
* @param array $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderNode(BpConfig $bp, Node $node, $path = array())
|
||||
{
|
||||
$table = Element::create(
|
||||
'table',
|
||||
array(
|
||||
'id' => $this->getId($node, $path),
|
||||
'class' => array(
|
||||
'bp',
|
||||
$node->getObjectClassName()
|
||||
)
|
||||
)
|
||||
);
|
||||
$attributes = $table->attributes();
|
||||
$attributes->add('class', $this->getStateClassNames($node));
|
||||
if ($node->isHandled()) {
|
||||
$attributes->add('class', 'handled');
|
||||
}
|
||||
if ($node->hasChildren()) {
|
||||
$attributes->add('class', 'operator');
|
||||
} else {
|
||||
$attributes->add('class', 'node');
|
||||
}
|
||||
|
||||
$tbody = $table->createElement('tbody');
|
||||
$tr = $tbody->createElement('tr');
|
||||
|
||||
if ($node->hasChildren()) {
|
||||
$tr->createElement(
|
||||
'th',
|
||||
array(
|
||||
'rowspan' => $node->countChildren() + 1 + ($this->isLocked() ? 0 : 1)
|
||||
)
|
||||
)->createElement(
|
||||
'span',
|
||||
array('class' => 'op')
|
||||
)->setContent($node->operatorHtml());
|
||||
}
|
||||
$td = $tr->createElement('td');
|
||||
|
||||
if ($node instanceof BpNode && $node->hasInfoUrl()) {
|
||||
$td->add($this->createInfoAction($node));
|
||||
}
|
||||
|
||||
if (! $this->isLocked()) {
|
||||
$td->addContent($this->getActionIcons($bp, $node));
|
||||
}
|
||||
|
||||
$link = $node->getLink();
|
||||
$link->attributes()->set('data-base-target', '_next');
|
||||
$link->addContent($this->getNodeIcons($node));
|
||||
|
||||
if ($node->hasChildren()) {
|
||||
$link->addContent($this->renderStateBadges($node->getStateSummary()));
|
||||
}
|
||||
|
||||
if ($time = $node->getLastStateChange()) {
|
||||
$since = $this->timeSince($time)->prependContent(
|
||||
sprintf(' (%s ', $node->getStateName())
|
||||
)->addContent(')');
|
||||
$link->addContent($since);
|
||||
}
|
||||
|
||||
$td->addContent($link);
|
||||
|
||||
foreach ($node->getChildren() as $name => $child) {
|
||||
$tbody->createElement('tr')->createElement('td')->setContent(
|
||||
$this->renderNode($bp, $child, $this->getCurrentPath())
|
||||
);
|
||||
}
|
||||
|
||||
if (! $this->isLocked() && $node instanceof BpNode) {
|
||||
$tbody->createElement('tr')->createElement('td')->setContent(
|
||||
$this->renderAddNewNode($node)
|
||||
);
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
protected function getActionIcons(BpConfig $bp, Node $node)
|
||||
{
|
||||
if ($node instanceof BpNode) {
|
||||
return $this->createEditAction($bp, $node);
|
||||
} else {
|
||||
return $this->createSimulationAction($bp, $node);
|
||||
}
|
||||
}
|
||||
|
||||
protected function createEditAction(BpConfig $bp, BpNode $node)
|
||||
{
|
||||
return $this->actionIcon(
|
||||
'wrench',
|
||||
Url::fromPath('businessprocess/node/edit', array(
|
||||
'config' => $bp->getName(),
|
||||
'node' => $node->getName()
|
||||
)),
|
||||
$this->translate('Modify this node')
|
||||
);
|
||||
}
|
||||
|
||||
protected function createSimulationAction(BpConfig $bp, Node $node)
|
||||
{
|
||||
return $this->actionIcon(
|
||||
'magic',
|
||||
$this->getUrl()->with(array(
|
||||
//'config' => $bp->getName(),
|
||||
'action' => 'simulation',
|
||||
'simulationnode' => $node->getName()
|
||||
)),
|
||||
$this->translate('Simulate a specific state')
|
||||
);
|
||||
}
|
||||
|
||||
protected function createInfoAction(BpNode $node)
|
||||
{
|
||||
$url = $node->getInfoUrl();
|
||||
return $this->actionIcon(
|
||||
'help',
|
||||
$url,
|
||||
sprintf('%s: %s', $this->translate('More information'), $url)
|
||||
);
|
||||
}
|
||||
protected function actionIcon($icon, $url, $title)
|
||||
{
|
||||
return Link::create(
|
||||
Icon::create($icon),
|
||||
$url,
|
||||
null,
|
||||
array(
|
||||
'title' => $title,
|
||||
'style' => 'float: right',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function renderAddNewNode($parent)
|
||||
{
|
||||
return Link::create(
|
||||
$this->translate('Add'),
|
||||
$this->getUrl()->with('action', 'add')->with('node', $parent->getName()),
|
||||
null,
|
||||
array(
|
||||
'class' => 'addnew icon-plus',
|
||||
'title' => $this->translate('Add a new business process node')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
||||
class ServiceNode extends Node
|
||||
class ServiceNode extends MonitoredNode
|
||||
{
|
||||
protected $hostname;
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ class ServiceNode extends Node
|
|||
|
||||
protected $className = 'service';
|
||||
|
||||
public function __construct(BusinessProcess $bp, $object)
|
||||
public function __construct(BpConfig $bp, $object)
|
||||
{
|
||||
$this->name = $object->hostname . ';' . $object->service;
|
||||
$this->hostname = $object->hostname;
|
||||
|
|
@ -25,46 +25,6 @@ class ServiceNode extends Node
|
|||
}
|
||||
}
|
||||
|
||||
public function renderLink($view)
|
||||
{
|
||||
if ($this->isMissing()) {
|
||||
return '<span class="missing">' . $view->escape($this->getAlias()) . '</span>';
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'host' => $this->getHostname(),
|
||||
'service' => $this->getServiceDescription()
|
||||
);
|
||||
if ($this->bp->hasBackendName()) {
|
||||
$params['backend'] = $this->bp->getBackendName();
|
||||
}
|
||||
$link = $view->qlink($this->getAlias(), 'monitoring/service/show', $params);
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
protected function getActionIcons($view)
|
||||
{
|
||||
$icons = array();
|
||||
|
||||
if (! $this->bp->isLocked()) {
|
||||
|
||||
$url = Url::fromPath( 'businessprocess/node/simulate', array(
|
||||
'config' => $this->bp->getName(),
|
||||
'node' => $this->name
|
||||
));
|
||||
|
||||
$icons[] = $this->actionIcon(
|
||||
$view,
|
||||
'magic',
|
||||
$url,
|
||||
'Simulation'
|
||||
);
|
||||
}
|
||||
|
||||
return $icons;
|
||||
}
|
||||
|
||||
public function getHostname()
|
||||
{
|
||||
return $this->hostname;
|
||||
|
|
@ -79,4 +39,18 @@ class ServiceNode extends Node
|
|||
{
|
||||
return $this->hostname . ': ' . $this->service;
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
$params = array(
|
||||
'host' => $this->getHostname(),
|
||||
'service' => $this->getServiceDescription()
|
||||
);
|
||||
|
||||
if ($this->bp->hasBackendName()) {
|
||||
$params['backend'] = $this->bp->getBackendName();
|
||||
}
|
||||
|
||||
return Url::fromPath('monitoring/service/show', $params);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,17 +2,18 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Web\Session\SessionNamespace;
|
||||
|
||||
class Simulation
|
||||
{
|
||||
/**
|
||||
* @var Session
|
||||
* @var SessionNamespace
|
||||
*/
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* @var BusinessProcess
|
||||
* @var BpConfig
|
||||
*/
|
||||
protected $bp;
|
||||
|
||||
|
|
@ -21,9 +22,12 @@ class Simulation
|
|||
*/
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $simulations;
|
||||
|
||||
public function __construct(BusinessProcess $bp, SessionNamespace $session)
|
||||
public function __construct(BpConfig $bp, SessionNamespace $session)
|
||||
{
|
||||
$this->bp = $bp;
|
||||
$this->session = $session;
|
||||
|
|
|
|||
133
library/Businessprocess/State/MonitoringState.php
Normal file
133
library/Businessprocess/State/MonitoringState.php
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\State;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Benchmark;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
|
||||
class MonitoringState
|
||||
{
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var MonitoringBackend */
|
||||
protected $backend;
|
||||
|
||||
private function __construct(BpConfig $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->backend = $config->getBackend();
|
||||
}
|
||||
|
||||
public static function apply(BpConfig $config)
|
||||
{
|
||||
$self = new static($config);
|
||||
$self->retrieveStatesFromBackend();
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function retrieveStatesFromBackend()
|
||||
{
|
||||
$config = $this->config;
|
||||
|
||||
try {
|
||||
$this->reallyRetrieveStatesFromBackend();
|
||||
} catch (Exception $e) {
|
||||
$config->addError(
|
||||
$config->translate('Could not retrieve process state: %s'),
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function reallyRetrieveStatesFromBackend()
|
||||
{
|
||||
$config = $this->config;
|
||||
|
||||
Benchmark::measure('Retrieving states for business process ' . $config->getName());
|
||||
$backend = $this->backend;
|
||||
$hostFilter = $config->listInvolvedHostNames();
|
||||
|
||||
if ($config->usesHardStates()) {
|
||||
$hostStateColumn = 'host_hard_state';
|
||||
$hostStateChangeColumn = 'host_last_hard_state_change';
|
||||
$serviceStateColumn = 'service_hard_state';
|
||||
$serviceStateChangeColumn = 'service_last_hard_state_change';
|
||||
} else {
|
||||
$hostStateColumn = 'host_state';
|
||||
$hostStateChangeColumn = 'host_last_state_change';
|
||||
$serviceStateColumn = 'service_state';
|
||||
$serviceStateChangeColumn = 'service_last_state_change';
|
||||
}
|
||||
$filter = Filter::matchAny();
|
||||
foreach ($hostFilter as $host) {
|
||||
$filter->addFilter(Filter::where('host_name', $host));
|
||||
}
|
||||
|
||||
if ($filter->isEmpty()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$hostStatus = $backend->select()->from('hostStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'last_state_change' => $hostStateChangeColumn,
|
||||
'in_downtime' => 'host_in_downtime',
|
||||
'ack' => 'host_acknowledged',
|
||||
'state' => $hostStateColumn
|
||||
))->applyFilter($filter)->getQuery()->fetchAll();
|
||||
|
||||
$serviceStatus = $backend->select()->from('serviceStatus', array(
|
||||
'hostname' => 'host_name',
|
||||
'service' => 'service_description',
|
||||
'last_state_change' => $serviceStateChangeColumn,
|
||||
'in_downtime' => 'service_in_downtime',
|
||||
'ack' => 'service_acknowledged',
|
||||
'state' => $serviceStateColumn
|
||||
))->applyFilter($filter)->getQuery()->fetchAll();
|
||||
|
||||
foreach ($serviceStatus as $row) {
|
||||
$this->handleDbRow($row, $config);
|
||||
}
|
||||
|
||||
foreach ($hostStatus as $row) {
|
||||
$this->handleDbRow($row, $config);
|
||||
}
|
||||
// TODO: Union, single query?
|
||||
Benchmark::measure('Got states for business process ' . $config->getName());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function handleDbRow($row, BpConfig $config)
|
||||
{
|
||||
$key = $row->hostname;
|
||||
if (property_exists($row, 'service')) {
|
||||
$key .= ';' . $row->service;
|
||||
} else {
|
||||
$key .= ';Hoststatus';
|
||||
}
|
||||
|
||||
// We fetch more states than we need, so skip unknown ones
|
||||
if (! $config->hasNode($key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$node = $config->getNode($key);
|
||||
|
||||
if ($row->state !== null) {
|
||||
$node->setState($row->state)->setMissing(false);
|
||||
}
|
||||
if ($row->last_state_change !== null) {
|
||||
$node->setLastStateChange($row->last_state_change);
|
||||
}
|
||||
if ((int) $row->in_downtime === 1) {
|
||||
$node->setDowntime(true);
|
||||
}
|
||||
if ((int) $row->ack === 1) {
|
||||
$node->setAck(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
91
library/Businessprocess/Storage/ConfigDiff.php
Normal file
91
library/Businessprocess/Storage/ConfigDiff.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Storage;
|
||||
|
||||
use Diff;
|
||||
use Diff_Renderer_Html_Inline;
|
||||
use Diff_Renderer_Html_SideBySide;
|
||||
use Diff_Renderer_Text_Context;
|
||||
use Diff_Renderer_Text_Unified;
|
||||
use Icinga\Module\Businessprocess\Html\Renderable;
|
||||
|
||||
class ConfigDiff implements Renderable
|
||||
{
|
||||
protected $a;
|
||||
|
||||
protected $b;
|
||||
|
||||
protected $diff;
|
||||
protected $opcodes;
|
||||
|
||||
protected function __construct($a, $b)
|
||||
{
|
||||
$this->requireVendorLib('Diff.php');
|
||||
|
||||
if (empty($a)) {
|
||||
$this->a = array();
|
||||
} else {
|
||||
$this->a = explode("\n", (string) $a);
|
||||
}
|
||||
|
||||
if (empty($b)) {
|
||||
$this->b = array();
|
||||
} else {
|
||||
$this->b = explode("\n", (string) $b);
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'context' => 5,
|
||||
// 'ignoreWhitespace' => true,
|
||||
// 'ignoreCase' => true,
|
||||
);
|
||||
$this->diff = new Diff($this->a, $this->b, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return $this->renderHtmlSideBySide();
|
||||
}
|
||||
|
||||
public function renderHtmlSideBySide()
|
||||
{
|
||||
$this->requireVendorLib('Diff/Renderer/Html/SideBySide.php');
|
||||
$renderer = new Diff_Renderer_Html_SideBySide;
|
||||
return $this->diff->render($renderer);
|
||||
}
|
||||
|
||||
public function renderHtmlInline()
|
||||
{
|
||||
$this->requireVendorLib('Diff/Renderer/Html/Inline.php');
|
||||
$renderer = new Diff_Renderer_Html_Inline;
|
||||
return $this->diff->render($renderer);
|
||||
}
|
||||
|
||||
public function renderTextContext()
|
||||
{
|
||||
$this->requireVendorLib('Diff/Renderer/Text/Context.php');
|
||||
$renderer = new Diff_Renderer_Text_Context;
|
||||
return $this->diff->render($renderer);
|
||||
}
|
||||
|
||||
public function renderTextUnified()
|
||||
{
|
||||
$this->requireVendorLib('Diff/Renderer/Text/Unified.php');
|
||||
$renderer = new Diff_Renderer_Text_Unified;
|
||||
return $this->diff->render($renderer);
|
||||
}
|
||||
|
||||
protected function requireVendorLib($file)
|
||||
{
|
||||
require_once dirname(dirname(__DIR__)) . '/vendor/php-diff/lib/' . $file;
|
||||
}
|
||||
|
||||
public static function create($a, $b)
|
||||
{
|
||||
$diff = new static($a, $b);
|
||||
return $diff;
|
||||
}
|
||||
}
|
||||
343
library/Businessprocess/Storage/LegacyConfigParser.php
Normal file
343
library/Businessprocess/Storage/LegacyConfigParser.php
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Storage;
|
||||
|
||||
use Icinga\Application\Benchmark;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\SystemPermissionException;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Metadata;
|
||||
|
||||
class LegacyConfigParser
|
||||
{
|
||||
/** @var int */
|
||||
protected $currentLineNumber;
|
||||
|
||||
/** @var string */
|
||||
protected $currentFilename;
|
||||
|
||||
protected $name;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* LegacyConfigParser constructor
|
||||
*
|
||||
* @param $name
|
||||
*/
|
||||
private function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->config = new BpConfig();
|
||||
$this->config->setName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpConfig
|
||||
*/
|
||||
public function getParsedConfig()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $filename
|
||||
*
|
||||
* @return BpConfig
|
||||
*/
|
||||
public static function parseFile($name, $filename)
|
||||
{
|
||||
Benchmark::measure('Loading business process ' . $name);
|
||||
$parser = new static($name);
|
||||
$parser->reallyParseFile($filename);
|
||||
Benchmark::measure('Business process ' . $name . ' loaded');
|
||||
return $parser->getParsedConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $string
|
||||
*
|
||||
* @return BpConfig
|
||||
*/
|
||||
public static function parseString($name, $string)
|
||||
{
|
||||
Benchmark::measure('Loading BP config from file: ' . $name);
|
||||
$parser = new static($name);
|
||||
foreach (preg_split('/\n/', $string) as $line) {
|
||||
$parser->parseLine($line);
|
||||
}
|
||||
|
||||
Benchmark::measure('Business process ' . $name . ' loaded');
|
||||
return $parser->getParsedConfig();
|
||||
}
|
||||
|
||||
protected function reallyParseFile($filename)
|
||||
{
|
||||
$file = $this->currentFilename = $filename;
|
||||
$fh = @fopen($file, 'r');
|
||||
if (! $fh) {
|
||||
throw new SystemPermissionException('Could not open "%s"', $filename);
|
||||
}
|
||||
|
||||
$config = $this->config;
|
||||
$config->setMetadata(
|
||||
$this::readMetadataFromFileHeader($config->getName(), $filename)
|
||||
);
|
||||
|
||||
$this->currentLineNumber = 0;
|
||||
while ($line = fgets($fh)) {
|
||||
$this->parseLine($line);
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
unset($this->currentLineNumber);
|
||||
unset($this->currentFilename);
|
||||
}
|
||||
|
||||
public static function readMetadataFromFileHeader($name, $filename)
|
||||
{
|
||||
$metadata = new Metadata($name);
|
||||
$fh = fopen($filename, 'r');
|
||||
$cnt = 0;
|
||||
while ($cnt < 15 && false !== ($line = fgets($fh))) {
|
||||
$cnt++;
|
||||
static::parseHeaderLine($line, $metadata);
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
protected function splitCommaSeparated($string)
|
||||
{
|
||||
return preg_split('/\s*,\s*/', $string, -1, PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
|
||||
protected function readHeaderString($string, Metadata $metadata)
|
||||
{
|
||||
foreach (preg_split('/\n/', $string) as $line) {
|
||||
$this->parseHeaderLine($line, $metadata);
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function emptyHeader()
|
||||
{
|
||||
return array(
|
||||
'Title' => null,
|
||||
'Description' => null,
|
||||
'Owner' => null,
|
||||
'AllowedUsers' => null,
|
||||
'AllowedGroups' => null,
|
||||
'AllowedRoles' => null,
|
||||
'Backend' => null,
|
||||
'Statetype' => 'soft',
|
||||
'SLAHosts' => null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $line
|
||||
* @param Metadata $metadata
|
||||
*/
|
||||
protected static function parseHeaderLine($line, Metadata $metadata)
|
||||
{
|
||||
if (preg_match('/^\s*#\s+(.+?)\s*:\s*(.+)$/', $line, $m)) {
|
||||
if ($metadata->hasKey($m[1])) {
|
||||
$metadata->set($m[1], $m[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $line
|
||||
* @param BpConfig $bp
|
||||
*/
|
||||
protected function parseDisplay(& $line, BpConfig $bp)
|
||||
{
|
||||
list($display, $name, $desc) = preg_split('~\s*;\s*~', substr($line, 8), 3);
|
||||
$bp->getBpNode($name)->setAlias($desc)->setDisplay($display);
|
||||
if ($display > 0) {
|
||||
$bp->addRootNode($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $line
|
||||
* @param BpConfig $bp
|
||||
*/
|
||||
protected function parseExternalInfo(& $line, BpConfig $bp)
|
||||
{
|
||||
list($name, $script) = preg_split('~\s*;\s*~', substr($line, 14), 2);
|
||||
$bp->getBpNode($name)->setInfoCommand($script);
|
||||
}
|
||||
|
||||
protected function parseExtraInfo(& $line, BpConfig $bp)
|
||||
{
|
||||
// TODO: Not yet
|
||||
// list($name, $script) = preg_split('~\s*;\s*~', substr($line, 14), 2);
|
||||
// $this->getNode($name)->setExtraInfo($script);
|
||||
}
|
||||
|
||||
protected function parseInfoUrl(& $line, BpConfig $bp)
|
||||
{
|
||||
list($name, $url) = preg_split('~\s*;\s*~', substr($line, 9), 2);
|
||||
$bp->getBpNode($name)->setInfoUrl($url);
|
||||
}
|
||||
|
||||
protected function parseExtraLine(& $line, $typeLength, BpConfig $bp)
|
||||
{
|
||||
$type = substr($line, 0, $typeLength);
|
||||
if (substr($type, 0, 7) === 'display') {
|
||||
$this->parseDisplay($line, $bp);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'external_info':
|
||||
$this->parseExternalInfo($line, $bp);
|
||||
break;
|
||||
case 'extra_info':
|
||||
$this->parseExtraInfo($line, $bp);
|
||||
break;
|
||||
case 'info_url':
|
||||
$this->parseInfoUrl($line, $bp);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a single line
|
||||
*
|
||||
* Adds eventual new knowledge to the given Business Process config
|
||||
*
|
||||
* @param $line
|
||||
*
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
protected function parseLine(& $line)
|
||||
{
|
||||
$bp = $this->config;
|
||||
$line = trim($line);
|
||||
|
||||
$this->currentLineNumber++;
|
||||
|
||||
// Skip empty or comment-only lines
|
||||
if (empty($line) || $line[0] === '#') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Semicolon found in the first 14 cols? Might be a line with extra information
|
||||
$pos = strpos($line, ';');
|
||||
if ($pos !== false && $pos < 14) {
|
||||
if ($this->parseExtraLine($line, $pos, $bp)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list($name, $value) = preg_split('~\s*=\s*~', $line, 2);
|
||||
|
||||
if (strpos($name, ';') !== false) {
|
||||
$this->parseError('No semicolon allowed in varname');
|
||||
}
|
||||
|
||||
$op = '&';
|
||||
if (preg_match_all('~([\|\+&\!])~', $value, $m)) {
|
||||
$op = implode('', $m[1]);
|
||||
for ($i = 1; $i < strlen($op); $i++) {
|
||||
if ($op[$i] !== $op[$i - 1]) {
|
||||
$this->parseError('Mixing operators is not allowed');
|
||||
}
|
||||
}
|
||||
}
|
||||
$op = $op[0];
|
||||
$op_name = $op;
|
||||
|
||||
if ($op === '+') {
|
||||
if (! preg_match('~^(\d+)(?::(\d+))?\s*of:\s*(.+?)$~', $value, $m)) {
|
||||
$this->parseError('syntax: <var> = <num> of: <var1> + <var2> [+ <varn>]*');
|
||||
}
|
||||
$op_name = $m[1];
|
||||
// New feature: $minWarn = $m[2];
|
||||
$value = $m[3];
|
||||
}
|
||||
$cmps = preg_split('~\s*\\' . $op . '\s*~', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$childNames = array();
|
||||
|
||||
foreach ($cmps as $val) {
|
||||
if (strpos($val, ';') !== false) {
|
||||
if ($bp->hasNode($val)) {
|
||||
$childNames[] = $val;
|
||||
continue;
|
||||
}
|
||||
|
||||
list($host, $service) = preg_split('~;~', $val, 2);
|
||||
if ($service === 'Hoststatus') {
|
||||
$bp->createHost($host);
|
||||
} else {
|
||||
$bp->createService($host, $service);
|
||||
}
|
||||
}
|
||||
if ($val[0] === '@') {
|
||||
if (strpos($val, ':') === false) {
|
||||
throw new ConfigurationError(
|
||||
"I'm unable to import full external configs, a node needs to be provided for '%s'",
|
||||
$val
|
||||
);
|
||||
// TODO: this might work:
|
||||
// $node = $bp->createImportedNode(substr($val, 1));
|
||||
} else {
|
||||
list($config, $nodeName) = preg_split('~:\s*~', substr($val, 1), 2);
|
||||
$node = $bp->createImportedNode($config, $nodeName);
|
||||
}
|
||||
$val = $node->getName();
|
||||
}
|
||||
|
||||
$childNames[] = $val;
|
||||
}
|
||||
|
||||
$node = new BpNode($bp, (object) array(
|
||||
'name' => $name,
|
||||
'operator' => $op_name,
|
||||
'child_names' => $childNames
|
||||
));
|
||||
|
||||
$bp->addNode($name, $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->currentFilename ?: '[given string]';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $msg
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
protected function parseError($msg)
|
||||
{
|
||||
throw new ConfigurationError(
|
||||
sprintf(
|
||||
'Parse error on %s:%s: %s',
|
||||
$this->getFilename(),
|
||||
$this->currentLineNumber,
|
||||
$msg
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
229
library/Businessprocess/Storage/LegacyConfigRenderer.php
Normal file
229
library/Businessprocess/Storage/LegacyConfigRenderer.php
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Storage;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
|
||||
class LegacyConfigRenderer
|
||||
{
|
||||
/** @var array */
|
||||
protected $renderedNodes;
|
||||
|
||||
/**
|
||||
* LecagyConfigRenderer constructor
|
||||
*
|
||||
* @param BpConfig $config
|
||||
*/
|
||||
public function __construct(BpConfig $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return $this->renderHeader() . $this->renderNodes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpConfig $config
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderConfig(BpConfig $config)
|
||||
{
|
||||
$renderer = new static($config);
|
||||
return $renderer->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function renderHeader()
|
||||
{
|
||||
$str = "### Business Process Config File ###\n#\n";
|
||||
|
||||
$meta = $this->config->getMetadata();
|
||||
foreach ($meta->getProperties() as $key => $value) {
|
||||
if ($value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$str .= sprintf("# %-15s : %s\n", $key, $value);
|
||||
}
|
||||
|
||||
$str .= "#\n###################################\n\n";
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function renderNodes()
|
||||
{
|
||||
$this->renderedNodes = array();
|
||||
|
||||
$config = $this->config;
|
||||
$str = '';
|
||||
|
||||
foreach ($config->getRootNodes() as $node) {
|
||||
$str .= $this->requireRenderedBpNode($node);
|
||||
}
|
||||
|
||||
foreach ($config->getUnboundNodes() as $name => $node) {
|
||||
$str .= $this->requireRenderedBpNode($node);
|
||||
}
|
||||
|
||||
return $str . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendered node definition, empty string if already rendered
|
||||
*
|
||||
* @param BpNode $node
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function requireRenderedBpNode(BpNode $node)
|
||||
{
|
||||
$name = $node->getName();
|
||||
|
||||
if (array_key_exists($name, $this->renderedNodes)) {
|
||||
|
||||
return '';
|
||||
} else {
|
||||
$this->renderedNodes[$name] = true;
|
||||
return $this->renderBpNode($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
protected function renderBpNode(BpNode $node)
|
||||
{
|
||||
$name = $node->getName();
|
||||
// Doing this before rendering children allows us to store loops
|
||||
$cfg = '';
|
||||
|
||||
foreach ($node->getChildBpNodes() as $name => $child) {
|
||||
$cfg .= $this->requireRenderedBpNode($child) . "\n";
|
||||
}
|
||||
|
||||
$cfg .= static::renderSingleBpNode($node);
|
||||
|
||||
return $cfg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
public static function renderEqualSign(BpNode $node)
|
||||
{
|
||||
$op = $node->getOperator();
|
||||
if (is_numeric($op)) {
|
||||
return '= ' . $op . ' of:';
|
||||
} else {
|
||||
return '=';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
public static function renderOperator(BpNode $node)
|
||||
{
|
||||
$op = $node->getOperator();
|
||||
if (is_numeric($op)) {
|
||||
return '+';
|
||||
} else {
|
||||
return $op;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
public static function renderSingleBpNode(BpNode $node)
|
||||
{
|
||||
return static::renderExpression($node)
|
||||
. static::renderDisplay($node)
|
||||
. static::renderInfoUrl($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
public static function renderExpression(BpNode $node)
|
||||
{
|
||||
return sprintf(
|
||||
"%s %s %s\n",
|
||||
$node->getName(),
|
||||
static::renderEqualSign($node),
|
||||
static::renderChildNames($node)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
public static function renderChildNames(BpNode $node)
|
||||
{
|
||||
$op = static::renderOperator($node);
|
||||
$children = $node->getChildNames();
|
||||
$str = implode(' ' . $op . ' ', $children);
|
||||
|
||||
if ((count($children) < 2) && $op !== '&') {
|
||||
|
||||
return $op . ' ' . $str;
|
||||
} else {
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
public static function renderDisplay(BpNode $node)
|
||||
{
|
||||
if ($node->hasAlias() || $node->getDisplay() > 0) {
|
||||
$prio = $node->getDisplay();
|
||||
return sprintf(
|
||||
"display %s;%s;%s\n",
|
||||
$prio,
|
||||
$node->getName(),
|
||||
$node->getAlias()
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $node
|
||||
* @return string
|
||||
*/
|
||||
public static function renderInfoUrl(BpNode $node)
|
||||
{
|
||||
if ($node->hasInfoUrl()) {
|
||||
return sprintf(
|
||||
"info_url;%s;%s\n",
|
||||
$node->getName(),
|
||||
$node->getInfoUrl()
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,109 +2,153 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess\Storage;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Storage\Storage;
|
||||
use DirectoryIterator;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Exception\SystemPermissionException;
|
||||
use Icinga\Application\Benchmark;
|
||||
|
||||
class LegacyStorage extends Storage
|
||||
{
|
||||
/** @var string */
|
||||
protected $configDir;
|
||||
|
||||
protected $parsing_line_number;
|
||||
|
||||
protected $currentFilename;
|
||||
|
||||
public function getConfigDir()
|
||||
{
|
||||
if ($this->configDir === null) {
|
||||
$dir = Icinga::app()
|
||||
->getModuleManager()
|
||||
->getModule('businessprocess')
|
||||
->getConfigDir();
|
||||
|
||||
// TODO: This is silly. We need Config::requireDirectory().
|
||||
if (! is_dir($dir)) {
|
||||
if (! is_dir(dirname($dir))) {
|
||||
if (! @mkdir(dirname($dir))) {
|
||||
throw new SystemPermissionException('Could not create config directory "%s"', dirname($dir));
|
||||
}
|
||||
}
|
||||
if (! mkdir($dir)) {
|
||||
throw new SystemPermissionException('Could not create config directory "%s"', $dir);
|
||||
}
|
||||
}
|
||||
$dir = $dir . '/processes';
|
||||
if (! is_dir($dir)) {
|
||||
if (! mkdir($dir)) {
|
||||
throw new SystemPermissionException('Could not create config directory "%s"', $dir);
|
||||
}
|
||||
}
|
||||
$this->configDir = $dir;
|
||||
$this->prepareDefaultConfigDir();
|
||||
}
|
||||
|
||||
return $this->configDir;
|
||||
}
|
||||
|
||||
protected function prepareDefaultConfigDir()
|
||||
{
|
||||
$dir = Icinga::app()
|
||||
->getModuleManager()
|
||||
->getModule('businessprocess')
|
||||
->getConfigDir();
|
||||
|
||||
// TODO: This is silly. We need Config::requireDirectory().
|
||||
if (! is_dir($dir)) {
|
||||
if (! is_dir(dirname($dir))) {
|
||||
if (! @mkdir(dirname($dir))) {
|
||||
throw new SystemPermissionException('Could not create config directory "%s"', dirname($dir));
|
||||
}
|
||||
}
|
||||
if (! mkdir($dir)) {
|
||||
throw new SystemPermissionException('Could not create config directory "%s"', $dir);
|
||||
}
|
||||
}
|
||||
$dir = $dir . '/processes';
|
||||
if (! is_dir($dir)) {
|
||||
if (! mkdir($dir)) {
|
||||
throw new SystemPermissionException('Could not create config directory "%s"', $dir);
|
||||
}
|
||||
}
|
||||
|
||||
$this->configDir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function listProcesses()
|
||||
{
|
||||
$files = array();
|
||||
foreach (new DirectoryIterator($this->getConfigDir()) as $file) {
|
||||
if($file->isDot()) continue;
|
||||
$filename = $file->getFilename();
|
||||
if (substr($filename, -5) === '.conf') {
|
||||
$name = substr($filename, 0, -5);
|
||||
$header = $this->readHeader($file->getPathname(), $name);
|
||||
if ($header['Title'] === null) {
|
||||
$files[$name] = $name;
|
||||
} else {
|
||||
$files[$name] = sprintf('%s (%s)', $header['Title'], $name);
|
||||
}
|
||||
|
||||
foreach ($this->listAllProcessNames() as $name) {
|
||||
$meta = $this->loadMetadata($name);
|
||||
if (! $meta->canRead()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[$name] = $meta->getExtendedTitle();
|
||||
}
|
||||
|
||||
natsort($files);
|
||||
natcasesort($files);
|
||||
return $files;
|
||||
}
|
||||
|
||||
protected function readHeader($file, $name)
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function listProcessNames()
|
||||
{
|
||||
$fh = fopen($file, 'r');
|
||||
$cnt = 0;
|
||||
$header = array(
|
||||
'Title' => null,
|
||||
'Owner' => null,
|
||||
'Backend' => null,
|
||||
'Statetype' => 'soft',
|
||||
'SLA Hosts' => null
|
||||
);
|
||||
while ($cnt < 15 && false !== ($line = fgets($fh))) {
|
||||
$cnt++;
|
||||
if (preg_match('/^\s*#\s+(.+?)\s*:\s*(.+)$/', $line, $m)) {
|
||||
if (array_key_exists($m[1], $header)) {
|
||||
$header[$m[1]] = $m[2];
|
||||
}
|
||||
$files = array();
|
||||
|
||||
foreach ($this->listAllProcessNames() as $name) {
|
||||
$meta = $this->loadMetadata($name);
|
||||
if (! $meta->canRead()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[$name] = $name;
|
||||
}
|
||||
return $header;
|
||||
|
||||
natcasesort($files);
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function storeProcess(BusinessProcess $process)
|
||||
public function listAllProcessNames()
|
||||
{
|
||||
$files = array();
|
||||
|
||||
foreach (new DirectoryIterator($this->getConfigDir()) as $file) {
|
||||
if ($file->isDot()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filename = $file->getFilename();
|
||||
if (substr($filename, -5) === '.conf') {
|
||||
$files[] = substr($filename, 0, -5);
|
||||
}
|
||||
}
|
||||
|
||||
natcasesort($files);
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function loadProcess($name)
|
||||
{
|
||||
return LegacyConfigParser::parseFile(
|
||||
$name,
|
||||
$this->getFilename($name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function storeProcess(BpConfig $process)
|
||||
{
|
||||
$filename = $this->getFilename($process->getName());
|
||||
$content = $process->toLegacyConfigString();
|
||||
file_put_contents(
|
||||
$filename,
|
||||
$content
|
||||
$this->getFilename($process->getName()),
|
||||
LegacyConfigRenderer::renderConfig($process)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function deleteProcess($name)
|
||||
{
|
||||
return @unlink($this->getFilename($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function loadMetadata($name)
|
||||
{
|
||||
return LegacyConfigParser::readMetadataFromFileHeader(
|
||||
$name,
|
||||
$this->getFilename($name)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -118,176 +162,28 @@ class LegacyStorage extends Storage
|
|||
return $this->getConfigDir() . '/' . $name . '.conf';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $string
|
||||
*
|
||||
* @return BpConfig
|
||||
*/
|
||||
public function loadFromString($name, $string)
|
||||
{
|
||||
$bp = new BusinessProcess();
|
||||
$bp->setName($name);
|
||||
$this->parseString($string, $bp);
|
||||
$this->loadHeader($name, $bp);
|
||||
return $bp;
|
||||
}
|
||||
|
||||
public function deleteProcess($name)
|
||||
{
|
||||
unlink($this->getFilename($name));
|
||||
return LegacyConfigParser::parseString($name, $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BusinessProcess
|
||||
* @param $name
|
||||
* @return bool
|
||||
*/
|
||||
public function loadProcess($name)
|
||||
public function hasProcess($name)
|
||||
{
|
||||
Benchmark::measure('Loading business process ' . $name);
|
||||
$bp = new BusinessProcess();
|
||||
$bp->setName($name);
|
||||
$this->parseFile($name, $bp);
|
||||
$this->loadHeader($name, $bp);
|
||||
Benchmark::measure('Business process ' . $name . ' loaded');
|
||||
return $bp;
|
||||
}
|
||||
|
||||
protected function loadHeader($name, $bp)
|
||||
{
|
||||
// TODO: do not open twice, this is quick and dirty based on existing code
|
||||
$file = $this->currentFilename = $this->getFilename($name);
|
||||
$header = $this->readHeader($file, $name);
|
||||
$bp->setTitle($header['Title']);
|
||||
if ($header['Backend']) {
|
||||
$bp->setBackendName($header['Backend']);
|
||||
}
|
||||
if ($header['Statetype'] === 'soft') {
|
||||
$bp->useSoftStates();
|
||||
}
|
||||
}
|
||||
|
||||
protected function parseFile($name, $bp)
|
||||
{
|
||||
$file = $this->currentFilename = $this->getFilename($name);
|
||||
$fh = @fopen($file, 'r');
|
||||
if (! $fh) {
|
||||
throw new SystemPermissionException('Could not open "%s"', $file);
|
||||
$file = $this->getFilename($name);
|
||||
if (! is_file($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->parsing_line_number = 0;
|
||||
while ($line = fgets($fh)) {
|
||||
$this->parseLine($line, $bp);
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
unset($this->parsing_line_number);
|
||||
unset($this->currentFilename);
|
||||
}
|
||||
|
||||
protected function parseString($string, $bp)
|
||||
{
|
||||
foreach (preg_split('/\n/', $string) as $line) {
|
||||
$this->parseLine($line, $bp);
|
||||
}
|
||||
}
|
||||
|
||||
protected function parseLine(& $line, $bp)
|
||||
{
|
||||
$line = trim($line);
|
||||
|
||||
$this->parsing_line_number++;
|
||||
|
||||
if (empty($line)) {
|
||||
return;
|
||||
}
|
||||
if ($line[0] === '#') {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: substr?
|
||||
if (preg_match('~^display~', $line)) {
|
||||
list($display, $name, $desc) = preg_split('~\s*;\s*~', substr($line, 8), 3);
|
||||
$node = $bp->getNode($name)->setAlias($desc)->setDisplay($display);
|
||||
if ($display > 0) {
|
||||
$bp->addRootNode($name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (preg_match('~^external_info~', $line)) {
|
||||
list($name, $script) = preg_split('~\s*;\s*~', substr($line, 14), 2);
|
||||
$node = $bp->getNode($name)->setInfoCommand($script);
|
||||
return;
|
||||
}
|
||||
|
||||
// New feature:
|
||||
// if (preg_match('~^extra_info~', $line)) {
|
||||
// list($name, $script) = preg_split('~\s*;\s*~', substr($line, 14), 2);
|
||||
// $node = $this->getNode($name)->setExtraInfo($script);
|
||||
// }
|
||||
|
||||
if (preg_match('~^info_url~', $line)) {
|
||||
list($name, $url) = preg_split('~\s*;\s*~', substr($line, 9), 2);
|
||||
$node = $bp->getNode($name)->setInfoUrl($url);
|
||||
return;
|
||||
}
|
||||
|
||||
list($name, $value) = preg_split('~\s*=\s*~', $line, 2);
|
||||
|
||||
if (strpos($name, ';') !== false) {
|
||||
$this->parseError('No semicolon allowed in varname');
|
||||
}
|
||||
|
||||
$op = '&';
|
||||
if (preg_match_all('~([\|\+&\!])~', $value, $m)) {
|
||||
$op = implode('', $m[1]);
|
||||
for ($i = 1; $i < strlen($op); $i++) {
|
||||
if ($op[$i] !== $op[$i - 1]) {
|
||||
$this->parseError('Mixing operators is not allowed');
|
||||
}
|
||||
}
|
||||
}
|
||||
$op = $op[0];
|
||||
$op_name = $op;
|
||||
|
||||
if ($op === '+') {
|
||||
if (! preg_match('~^(\d+)\s*of:\s*(.+?)$~', $value, $m)) {
|
||||
$this->parseError('syntax: <var> = <num> of: <var1> + <var2> [+ <varn>]*');
|
||||
}
|
||||
$op_name = $m[1];
|
||||
$value = $m[2];
|
||||
}
|
||||
$cmps = preg_split('~\s*\\' . $op . '\s*~', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
foreach ($cmps as & $val) {
|
||||
if (strpos($val, ';') !== false) {
|
||||
if ($bp->hasNode($val)) continue;
|
||||
|
||||
list($host, $service) = preg_split('~;~', $val, 2);
|
||||
if ($service === 'Hoststatus') {
|
||||
$bp->createHost($host);
|
||||
} else {
|
||||
$bp->createService($host, $service);
|
||||
}
|
||||
}
|
||||
if ($val[0] === '@' && strpos($val, ':') !== false) {
|
||||
list($config, $nodeName) = preg_split('~:\s*~', substr($val, 1), 2);
|
||||
$bp->createImportedNode($config, $nodeName);
|
||||
$val = $nodeName;
|
||||
}
|
||||
}
|
||||
|
||||
$node = new BpNode($bp, (object) array(
|
||||
'name' => $name,
|
||||
'operator' => $op_name,
|
||||
'child_names' => $cmps
|
||||
));
|
||||
$bp->addNode($name, $node);
|
||||
}
|
||||
|
||||
protected function parseError($msg)
|
||||
{
|
||||
throw new ConfigurationError(
|
||||
sprintf(
|
||||
'Parse error on %s:%s: %s',
|
||||
$this->currentFilename,
|
||||
$this->parsing_line_number,
|
||||
$msg
|
||||
)
|
||||
);
|
||||
return $this->loadMetadata($name)->canRead();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,20 @@
|
|||
namespace Icinga\Module\Businessprocess\Storage;
|
||||
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Metadata;
|
||||
|
||||
abstract class Storage
|
||||
{
|
||||
/**
|
||||
* @var ConfigObject
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Storage constructor.
|
||||
* @param ConfigObject $config
|
||||
*/
|
||||
public function __construct(ConfigObject $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
|
|
@ -20,18 +28,65 @@ abstract class Storage
|
|||
}
|
||||
|
||||
/**
|
||||
* All processes readable by the current user
|
||||
*
|
||||
* The returned array has the form <process name> => <nice title>, sorted
|
||||
* by title
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function listProcesses();
|
||||
|
||||
/**
|
||||
* @return BusinessProcess
|
||||
* All process names readable by the current user
|
||||
*
|
||||
* The returned array has the form <process name> => <process name> and is
|
||||
* sorted
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function listProcessNames();
|
||||
|
||||
/**
|
||||
* All available process names, regardless of eventual restrictions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function listAllProcessNames();
|
||||
|
||||
/**
|
||||
* Whether a configuration with the given name exists
|
||||
*
|
||||
* @param $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function hasProcess($name);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return BpConfig
|
||||
*/
|
||||
abstract public function loadProcess($name);
|
||||
|
||||
/**
|
||||
* Store eventual changes applied to the given configuration
|
||||
*
|
||||
* @param BpConfig $config
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function storeProcess(BusinessProcess $name);
|
||||
abstract public function storeProcess(BpConfig $config);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return bool Whether the process has been deleted
|
||||
*/
|
||||
abstract public function deleteProcess($name);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return Metadata
|
||||
*/
|
||||
abstract public function loadMetadata($name);
|
||||
}
|
||||
|
|
|
|||
76
library/Businessprocess/Test/BaseTestCase.php
Normal file
76
library/Businessprocess/Test/BaseTestCase.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Test;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\ApplicationBootstrap;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
use Icinga\Module\Businessprocess\Web\FakeRequest;
|
||||
use PHPUnit_Framework_TestCase;
|
||||
|
||||
abstract class BaseTestCase extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var ApplicationBootstrap */
|
||||
private static $app;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->app();
|
||||
FakeRequest::setConfiguredBaseUrl('/icingaweb2/');
|
||||
}
|
||||
|
||||
protected function emptyConfigSection()
|
||||
{
|
||||
return Config::module('businessprocess')->getSection('global');
|
||||
}
|
||||
|
||||
/***
|
||||
* @return BpConfig
|
||||
*/
|
||||
protected function makeLoop()
|
||||
{
|
||||
return $this->makeInstance()->loadFromString(
|
||||
'loop',
|
||||
"a = b\nb = c\nc = a\nd = a"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LegacyStorage
|
||||
*/
|
||||
protected function makeInstance()
|
||||
{
|
||||
return new LegacyStorage($this->emptyConfigSection());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $subDir
|
||||
* @return string
|
||||
*/
|
||||
protected function getTestsBaseDir($subDir = null)
|
||||
{
|
||||
$dir = dirname(dirname(dirname(__DIR__))) . '/test';
|
||||
if ($subDir === null) {
|
||||
return $dir;
|
||||
} else {
|
||||
return $dir . '/' . ltrim($subDir, '/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApplicationBootstrap
|
||||
*/
|
||||
protected function app()
|
||||
{
|
||||
if (self::$app === null) {
|
||||
self::$app = Icinga::app();
|
||||
}
|
||||
|
||||
return self::$app;
|
||||
}
|
||||
}
|
||||
28
library/Businessprocess/Test/Bootstrap.php
Normal file
28
library/Businessprocess/Test/Bootstrap.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Test;
|
||||
|
||||
use Icinga\Application\Cli;
|
||||
|
||||
class Bootstrap
|
||||
{
|
||||
public static function cli($basedir = null)
|
||||
{
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
if ($basedir === null) {
|
||||
$basedir = dirname(dirname(dirname(__DIR__)));
|
||||
}
|
||||
$testsDir = $basedir . '/test';
|
||||
require_once 'Icinga/Application/Cli.php';
|
||||
|
||||
if (array_key_exists('ICINGAWEB_CONFIGDIR', $_SERVER)) {
|
||||
$configDir = $_SERVER['ICINGAWEB_CONFIGDIR'];
|
||||
} else {
|
||||
$configDir = $testsDir . '/config';
|
||||
}
|
||||
|
||||
Cli::start($testsDir, $configDir)
|
||||
->getModuleManager()
|
||||
->loadModule('businessprocess', $basedir);
|
||||
}
|
||||
}
|
||||
15
library/Businessprocess/Web/Component/ActionBar.php
Normal file
15
library/Businessprocess/Web/Component/ActionBar.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
|
||||
class ActionBar extends BaseElement
|
||||
{
|
||||
protected $contentSeparator = ' ';
|
||||
|
||||
/** @var string */
|
||||
protected $tag = 'div';
|
||||
|
||||
protected $defaultAttributes = array('class' => 'action-bar');
|
||||
}
|
||||
12
library/Businessprocess/Web/Component/Content.php
Normal file
12
library/Businessprocess/Web/Component/Content.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
|
||||
class Content extends Container
|
||||
{
|
||||
protected $contentSeparator = "\n";
|
||||
|
||||
protected $defaultAttributes = array('class' => 'content');
|
||||
}
|
||||
12
library/Businessprocess/Web/Component/Controls.php
Normal file
12
library/Businessprocess/Web/Component/Controls.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
|
||||
class Controls extends Container
|
||||
{
|
||||
protected $contentSeparator = "\n";
|
||||
|
||||
protected $defaultAttributes = array('class' => 'controls');
|
||||
}
|
||||
108
library/Businessprocess/Web/Component/Dashboard.php
Normal file
108
library/Businessprocess/Web/Component/Dashboard.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
use Icinga\Module\Businessprocess\Html\HtmlTag;
|
||||
use Icinga\Module\Businessprocess\Storage\Storage;
|
||||
|
||||
class Dashboard extends BaseElement
|
||||
{
|
||||
/** @var string */
|
||||
protected $contentSeparator = "\n";
|
||||
|
||||
/** @var string */
|
||||
protected $tag = 'div';
|
||||
|
||||
protected $defaultAttributes = array(
|
||||
'class' => 'overview-dashboard',
|
||||
'data-base-target' => '_next'
|
||||
);
|
||||
|
||||
/** @var Auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var Storage */
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Dashboard constructor.
|
||||
* @param Auth $auth
|
||||
* @param Storage $storage
|
||||
*/
|
||||
protected function __construct(Auth $auth, Storage $storage)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->storage = $storage;
|
||||
// TODO: Auth?
|
||||
$processes = $storage->listProcessNames();
|
||||
$this->add(
|
||||
HtmlTag::h1($this->translate('Welcome to your Business Process Overview'))
|
||||
);
|
||||
$this->add(
|
||||
HtmlTag::p(
|
||||
$this->translate(
|
||||
'From here you can reach all your defined Business Process'
|
||||
. ' configurations, create new or modify existing ones'
|
||||
)
|
||||
)
|
||||
);
|
||||
if ($auth->hasPermission('businessprocess/create')) {
|
||||
$this->add(
|
||||
new DashboardAction(
|
||||
$this->translate('Create'),
|
||||
$this->translate('Create a new Business Process configuration'),
|
||||
'plus',
|
||||
'businessprocess/process/create',
|
||||
null,
|
||||
array('class' => 'addnew')
|
||||
)
|
||||
)->add(
|
||||
new DashboardAction(
|
||||
$this->translate('Upload'),
|
||||
$this->translate('Upload an existing Business Process configuration'),
|
||||
'upload',
|
||||
'businessprocess/process/upload',
|
||||
null,
|
||||
array('class' => 'addnew')
|
||||
)
|
||||
);
|
||||
|
||||
} elseif (empty($processes)) {
|
||||
$this->addContent(
|
||||
Container::create()
|
||||
->add(HtmlTag::h1($this->translate('Not available')))
|
||||
->add(HtmlTag::p($this->translate('No Business Process has been defined for you')))
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($processes as $name) {
|
||||
$meta = $storage->loadMetadata($name);
|
||||
$title = $meta->get('Title');
|
||||
if ($title) {
|
||||
$title = sprintf('%s (%s)', $title, $name);
|
||||
} else {
|
||||
$title = $name;
|
||||
}
|
||||
$this->add(new DashboardAction(
|
||||
$title,
|
||||
$meta->get('Description'),
|
||||
'sitemap',
|
||||
'businessprocess/process/show',
|
||||
array('config' => $name)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Auth $auth
|
||||
* @param Storage $storage
|
||||
* @return static
|
||||
*/
|
||||
public static function create(Auth $auth, Storage $storage)
|
||||
{
|
||||
return new static($auth, $storage);
|
||||
}
|
||||
}
|
||||
29
library/Businessprocess/Web/Component/DashboardAction.php
Normal file
29
library/Businessprocess/Web/Component/DashboardAction.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
use Icinga\Module\Businessprocess\Html\Element;
|
||||
use Icinga\Module\Businessprocess\Html\Icon;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
|
||||
class DashboardAction extends BaseElement
|
||||
{
|
||||
protected $tag = 'div';
|
||||
|
||||
protected $defaultAttributes = array('class' => 'action');
|
||||
|
||||
public function __construct($title, $description, $icon, $url, $urlParams = null, $attributes = null)
|
||||
{
|
||||
$this->add(
|
||||
Link::create(
|
||||
Icon::create($icon),
|
||||
$url,
|
||||
$urlParams,
|
||||
$attributes
|
||||
)->add(
|
||||
Element::create('span', array('class' => 'header'))->addContent($title)
|
||||
)->addContent($description)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Renderer\Renderer;
|
||||
use Icinga\Module\Businessprocess\Renderer\TreeRenderer;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
||||
class RenderedProcessActionBar extends ActionBar
|
||||
{
|
||||
public function __construct(BpConfig $config, Renderer $renderer, Auth $auth, Url $url)
|
||||
{
|
||||
$meta = $config->getMetadata();
|
||||
|
||||
if ($renderer instanceof TreeRenderer) {
|
||||
$this->add(
|
||||
Link::create(
|
||||
$this->translate('Tiles'),
|
||||
$url->with('mode', 'tile'),
|
||||
null,
|
||||
array('class' => 'icon-dashboard')
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->add(
|
||||
Link::create(
|
||||
$this->translate('Tree'),
|
||||
$url->with('mode', 'tree'),
|
||||
null,
|
||||
array('class' => 'icon-sitemap')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->add(
|
||||
Link::create(
|
||||
$this->translate('Fullscreen'),
|
||||
$url->with('showFullscreen', true),
|
||||
null,
|
||||
array(
|
||||
'class' => 'icon-resize-full-alt',
|
||||
'title' => $this->translate('Switch to fullscreen mode'),
|
||||
'data-base-target' => '_main',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$hasChanges = $config->hasSimulations() || $config->hasBeenChanged();
|
||||
|
||||
if ($renderer->isLocked()) {
|
||||
$this->add(
|
||||
Link::create(
|
||||
$this->translate('Unlock'),
|
||||
$url->with('unlocked', true),
|
||||
null,
|
||||
array(
|
||||
'class' => 'icon-lock-open',
|
||||
'title' => $this->translate('Unlock this process'),
|
||||
)
|
||||
)
|
||||
);
|
||||
} elseif (! $hasChanges) {
|
||||
$this->add(
|
||||
Link::create(
|
||||
$this->translate('Lock'),
|
||||
$url->without('unlocked')->without('action'),
|
||||
null,
|
||||
array(
|
||||
'class' => 'icon-lock',
|
||||
'title' => $this->translate('Lock this process'),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($hasChanges || (! $renderer->isLocked()) && $meta->canModify()) {
|
||||
$this->add(
|
||||
Link::create(
|
||||
$this->translate('Config'),
|
||||
'businessprocess/process/config',
|
||||
$this->currentProcessParams($url),
|
||||
array(
|
||||
'class' => 'icon-wrench',
|
||||
'title' => $this->translate('Modify this process'),
|
||||
'data-base-target' => '_next',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function currentProcessParams($url)
|
||||
{
|
||||
$urlParams = $url->getParams();
|
||||
$params = array();
|
||||
foreach (array('config', 'node') as $name) {
|
||||
if ($value = $urlParams->get($name)) {
|
||||
$params[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
10
library/Businessprocess/Web/Component/Tabs.php
Normal file
10
library/Businessprocess/Web/Component/Tabs.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Module\Businessprocess\Html\Renderable;
|
||||
use Icinga\Web\Widget\Tabs as WebTabs;
|
||||
|
||||
class Tabs extends WebTabs implements Renderable
|
||||
{
|
||||
}
|
||||
266
library/Businessprocess/Web/Controller.php
Normal file
266
library/Businessprocess/Web/Controller.php
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Html\HtmlTag;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
use Icinga\Module\Businessprocess\Storage\Storage;
|
||||
use Icinga\Module\Businessprocess\Web\Component\ActionBar;
|
||||
use Icinga\Module\Businessprocess\Web\Component\Controls;
|
||||
use Icinga\Module\Businessprocess\Web\Component\Content;
|
||||
use Icinga\Module\Businessprocess\Web\Component\Tabs;
|
||||
use Icinga\Module\Businessprocess\Web\Form\FormLoader;
|
||||
use Icinga\Web\Controller as ModuleController;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\View;
|
||||
|
||||
class Controller extends ModuleController
|
||||
{
|
||||
/** @var View */
|
||||
public $view;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $bp;
|
||||
|
||||
/** @var Tabs */
|
||||
protected $mytabs;
|
||||
|
||||
/** @var Storage */
|
||||
private $storage;
|
||||
|
||||
/** @var bool */
|
||||
protected $showFullscreen;
|
||||
|
||||
/** @var Url */
|
||||
private $url;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$m = Icinga::app()->getModuleManager();
|
||||
if (! $m->hasLoaded('monitoring') && $m->hasInstalled('monitoring')) {
|
||||
$m->loadModule('monitoring');
|
||||
}
|
||||
$this->controls();
|
||||
$this->content();
|
||||
$this->url();
|
||||
$this->view->showFullscreen
|
||||
= $this->showFullscreen
|
||||
= (bool) $this->_helper->layout()->showFullscreen;
|
||||
|
||||
$this->view->compact = $this->params->get('view') === 'compact';
|
||||
$this->setViewScript('default');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Url
|
||||
*/
|
||||
protected function url()
|
||||
{
|
||||
if ($this->url === null) {
|
||||
$this->url = Url::fromPath(
|
||||
$this->getRequest()->getUrl()->getPath()
|
||||
)->setParams($this->params);
|
||||
}
|
||||
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ActionBar
|
||||
*/
|
||||
protected function actions()
|
||||
{
|
||||
if ($this->view->actions === null) {
|
||||
$this->view->actions = new ActionBar();
|
||||
}
|
||||
|
||||
return $this->view->actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Controls
|
||||
*/
|
||||
protected function controls()
|
||||
{
|
||||
if ($this->view->controls === null) {
|
||||
$this->view->controls = Controls::create();
|
||||
}
|
||||
|
||||
return $this->view->controls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Content
|
||||
*/
|
||||
protected function content()
|
||||
{
|
||||
if ($this->view->content === null) {
|
||||
$this->view->content = Content::create();
|
||||
}
|
||||
|
||||
return $this->view->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $label
|
||||
* @return Tabs
|
||||
*/
|
||||
protected function singleTab($label)
|
||||
{
|
||||
return $this->tabs()->add(
|
||||
'tab',
|
||||
array(
|
||||
'label' => $label,
|
||||
'url' => $this->getRequest()->getUrl()
|
||||
)
|
||||
)->activate('tab');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tabs
|
||||
*/
|
||||
protected function defaultTab()
|
||||
{
|
||||
return $this->singleTab($this->translate('Business Process'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tabs
|
||||
*/
|
||||
protected function overviewTab()
|
||||
{
|
||||
return $this->tabs()->add(
|
||||
'overview',
|
||||
array(
|
||||
'label' => $this->translate('Business Process'),
|
||||
'url' => 'businessprocess'
|
||||
)
|
||||
)->activate('overview');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tabs
|
||||
*/
|
||||
protected function tabs()
|
||||
{
|
||||
// Todo: do not add to view once all of them render controls()
|
||||
if ($this->mytabs === null) {
|
||||
$tabs = new Tabs();
|
||||
//$this->controls()->add($tabs);
|
||||
$this->mytabs = $tabs;
|
||||
}
|
||||
|
||||
return $this->mytabs;
|
||||
}
|
||||
|
||||
protected function session()
|
||||
{
|
||||
return $this->Window()->getSessionNamespace('businessprocess');
|
||||
}
|
||||
|
||||
protected function setViewScript($name)
|
||||
{
|
||||
$this->_helper->viewRenderer->setNoController(true);
|
||||
$this->_helper->viewRenderer->setScriptAction($name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function setTitle($title)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$this->view->title = vsprintf($title, $args);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addTitle($title)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$this->view->title = vsprintf($title, $args);
|
||||
$this->controls()->add(HtmlTag::h1($this->view->title));
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadModifiedBpConfig()
|
||||
{
|
||||
$bp = $this->loadBpConfig();
|
||||
$changes = ProcessChanges::construct($bp, $this->session());
|
||||
if ($this->params->get('dismissChanges')) {
|
||||
Notification::success(
|
||||
sprintf(
|
||||
$this->translate('%d pending change(s) have been dropped'),
|
||||
$changes->count()
|
||||
)
|
||||
);
|
||||
$changes->clear();
|
||||
$this->redirectNow($this->url()->without('dismissChanges')->without('unlocked'));
|
||||
}
|
||||
$bp->applyChanges($changes);
|
||||
return $bp;
|
||||
}
|
||||
|
||||
protected function doNotRender()
|
||||
{
|
||||
$this->_helper->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadBpConfig()
|
||||
{
|
||||
$name = $this->params->get('config');
|
||||
$storage = $this->storage();
|
||||
|
||||
if (! $storage->hasProcess($name)) {
|
||||
$this->httpNotFound(
|
||||
$this->translate('No such process config: "%s"'),
|
||||
$name
|
||||
);
|
||||
}
|
||||
|
||||
$modifications = $this->session()->get('modifications', array());
|
||||
if (array_key_exists($name, $modifications)) {
|
||||
$bp = $storage->loadFromString($name, $modifications[$name]);
|
||||
} else {
|
||||
$bp = $storage->loadProcess($name);
|
||||
}
|
||||
|
||||
// allow URL parameter to override configured state type
|
||||
if (null !== ($stateType = $this->params->get('state_type'))) {
|
||||
if ($stateType === 'soft') {
|
||||
$bp->useSoftStates();
|
||||
}
|
||||
if ($stateType === 'hard') {
|
||||
$bp->useHardStates();
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->bpconfig = $this->bp = $bp;
|
||||
$this->view->configName = $bp->getName();
|
||||
|
||||
return $bp;
|
||||
}
|
||||
|
||||
public function loadForm($name)
|
||||
{
|
||||
return FormLoader::load($name, $this->Module());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LegacyStorage|Storage
|
||||
*/
|
||||
protected function storage()
|
||||
{
|
||||
if ($this->storage === null) {
|
||||
$this->storage = new LegacyStorage(
|
||||
$this->Config()->getSection('global')
|
||||
);
|
||||
}
|
||||
|
||||
return $this->storage;
|
||||
}
|
||||
}
|
||||
26
library/Businessprocess/Web/FakeRequest.php
Normal file
26
library/Businessprocess/Web/FakeRequest.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Web\Request;
|
||||
|
||||
class FakeRequest extends Request
|
||||
{
|
||||
/** @var string */
|
||||
private static $baseUrl;
|
||||
|
||||
public static function setConfiguredBaseUrl($url)
|
||||
{
|
||||
self::$baseUrl = $url;
|
||||
}
|
||||
|
||||
public function getBaseUrl($raw = false)
|
||||
{
|
||||
if (self::$baseUrl === null) {
|
||||
throw new ProgrammingError('Cannot determine base URL on CLI if not configured');
|
||||
} else {
|
||||
return self::$baseUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
library/Businessprocess/Web/Form/Element/FormElement.php
Normal file
9
library/Businessprocess/Web/Form/Element/FormElement.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Form\Element;
|
||||
|
||||
use Zend_Form_Element_Xhtml;
|
||||
|
||||
class FormElement extends Zend_Form_Element_Xhtml
|
||||
{
|
||||
}
|
||||
22
library/Businessprocess/Web/Form/Element/SimpleNote.php
Normal file
22
library/Businessprocess/Web/Form/Element/SimpleNote.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Form\Element;
|
||||
|
||||
class SimpleNote extends FormElement
|
||||
{
|
||||
public $helper = 'formSimpleNote';
|
||||
|
||||
/**
|
||||
* Always ignore this element
|
||||
* @codingStandardsIgnoreStart
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_ignore = true;
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
public function isValid($value, $context = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
167
library/Businessprocess/Web/Form/QuickBaseForm.php
Normal file
167
library/Businessprocess/Web/Form/QuickBaseForm.php
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Web\Form;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Modules\Module;
|
||||
use Icinga\Module\Businessprocess\Html\Renderable;
|
||||
use Zend_Form;
|
||||
|
||||
abstract class QuickBaseForm extends Zend_Form implements Renderable
|
||||
{
|
||||
/**
|
||||
* The Icinga module this form belongs to. Usually only set if the
|
||||
* form is initialized through the FormLoader
|
||||
*
|
||||
* @var Module
|
||||
*/
|
||||
protected $icingaModule;
|
||||
|
||||
protected $icingaModuleName;
|
||||
|
||||
private $hintCount = 0;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
$this->callZfConstructor($this->handleOptions($options))
|
||||
->initializePrefixPaths();
|
||||
}
|
||||
|
||||
protected function callZfConstructor($options = null)
|
||||
{
|
||||
parent::__construct($options);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function initializePrefixPaths()
|
||||
{
|
||||
$this->addPrefixPathsForBusinessprocess();
|
||||
if ($this->icingaModule && $this->icingaModuleName !== 'businessprocess') {
|
||||
$this->addPrefixPathsForModule($this->icingaModule);
|
||||
}
|
||||
}
|
||||
|
||||
protected function addPrefixPathsForBusinessprocess()
|
||||
{
|
||||
$module = Icinga::app()
|
||||
->getModuleManager()
|
||||
->loadModule('businessprocess')
|
||||
->getModule('businessprocess');
|
||||
|
||||
$this->addPrefixPathsForModule($module);
|
||||
}
|
||||
|
||||
public function addPrefixPathsForModule(Module $module)
|
||||
{
|
||||
$basedir = sprintf(
|
||||
'%s/%s/Web/Form',
|
||||
$module->getLibDir(),
|
||||
ucfirst($module->getName())
|
||||
);
|
||||
|
||||
$this->addPrefixPaths(array(
|
||||
array(
|
||||
'prefix' => __NAMESPACE__ . '\\Element\\',
|
||||
'path' => $basedir . '/Element',
|
||||
'type' => static::ELEMENT
|
||||
)
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addHidden($name, $value = null)
|
||||
{
|
||||
$this->addElement('hidden', $name);
|
||||
$el = $this->getElement($name);
|
||||
$el->setDecorators(array('ViewHelper'));
|
||||
if ($value !== null) {
|
||||
$this->setDefault($name, $value);
|
||||
$el->setValue($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// TODO: Should be an element
|
||||
public function addHtmlHint($html, $options = array())
|
||||
{
|
||||
return $this->addHtml('<div class="hint">' . $html . '</div>', $options);
|
||||
}
|
||||
|
||||
public function addHtml($html, $options = array())
|
||||
{
|
||||
if (array_key_exists('name', $options)) {
|
||||
$name = $options['name'];
|
||||
unset($options['name']);
|
||||
} else {
|
||||
$name = '_HINT' . ++$this->hintCount;
|
||||
}
|
||||
|
||||
$this->addElement('simpleNote', $name, $options);
|
||||
$this->getElement($name)
|
||||
->setValue($html)
|
||||
->setIgnore(true)
|
||||
->setDecorators(array('ViewHelper'));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function optionalEnum($enum, $nullLabel = null)
|
||||
{
|
||||
if ($nullLabel === null) {
|
||||
$nullLabel = $this->translate('- please choose -');
|
||||
}
|
||||
|
||||
return array(null => $nullLabel) + $enum;
|
||||
}
|
||||
|
||||
protected function handleOptions($options = null)
|
||||
{
|
||||
if ($options === null) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (array_key_exists('icingaModule', $options)) {
|
||||
/** @var Module icingaModule */
|
||||
$this->icingaModule = $options['icingaModule'];
|
||||
$this->icingaModuleName = $this->icingaModule->getName();
|
||||
unset($options['icingaModule']);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public function setIcingaModule(Module $module)
|
||||
{
|
||||
$this->icingaModule = $module;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadForm($name, Module $module = null)
|
||||
{
|
||||
if ($module === null) {
|
||||
$module = $this->icingaModule;
|
||||
}
|
||||
|
||||
return FormLoader::load($name, $module);
|
||||
}
|
||||
|
||||
protected function valueIsEmpty($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return empty($value);
|
||||
}
|
||||
|
||||
return strlen($value) === 0;
|
||||
}
|
||||
|
||||
public function translate($string)
|
||||
{
|
||||
if ($this->icingaModuleName === null) {
|
||||
return t($string);
|
||||
} else {
|
||||
return mt($this->icingaModuleName, $string);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue