mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-27 07:44:04 +02:00
Merge branch 'master' into feature/deduplicate-puppet-code-6842
Conflicts: .vagrant-puppet/manifests/default.pp
This commit is contained in:
commit
b82ed3d2a4
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
development/
|
||||||
|
|
||||||
# ./configure output
|
# ./configure output
|
||||||
config.log
|
config.log
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace Icinga\Clicommands;
|
namespace Icinga\Clicommands;
|
||||||
|
|
||||||
use Icinga\Cli\Command;
|
use Icinga\Cli\Command;
|
||||||
use Exception;
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
class WebCommand extends Command
|
class WebCommand extends Command
|
||||||
{
|
{
|
||||||
@ -13,11 +13,11 @@ class WebCommand extends Command
|
|||||||
{
|
{
|
||||||
$minVersion = '5.4.0';
|
$minVersion = '5.4.0';
|
||||||
if (version_compare(PHP_VERSION, $minVersion) < 0) {
|
if (version_compare(PHP_VERSION, $minVersion) < 0) {
|
||||||
throw new Exception(sprintf(
|
throw new IcingaException(
|
||||||
'You are running PHP %s, internal webserver requires %s.',
|
'You are running PHP %s, internal webserver requires %s.',
|
||||||
PHP_VERSION,
|
PHP_VERSION,
|
||||||
$minVersion
|
$minVersion
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fork = $this->params->get('daemonize');
|
$fork = $this->params->get('daemonize');
|
||||||
@ -27,12 +27,12 @@ class WebCommand extends Command
|
|||||||
// TODO: Sanity check!!
|
// TODO: Sanity check!!
|
||||||
if ($socket === null) {
|
if ($socket === null) {
|
||||||
$socket = '0.0.0.0:80';
|
$socket = '0.0.0.0:80';
|
||||||
// throw new Exception('Socket is required');
|
// throw new IcingaException('Socket is required');
|
||||||
}
|
}
|
||||||
if ($basedir === null) {
|
if ($basedir === null) {
|
||||||
$basedir = dirname(ICINGAWEB_APPDIR) . '/public';
|
$basedir = dirname(ICINGAWEB_APPDIR) . '/public';
|
||||||
if (! file_exists($basedir) || ! is_dir($basedir)) {
|
if (! file_exists($basedir) || ! is_dir($basedir)) {
|
||||||
throw new Exception('Basedir is required');
|
throw new IcingaException('Basedir is required');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$basedir = realpath($basedir);
|
$basedir = realpath($basedir);
|
||||||
@ -68,7 +68,7 @@ class WebCommand extends Command
|
|||||||
{
|
{
|
||||||
$pid = pcntl_fork();
|
$pid = pcntl_fork();
|
||||||
if ($pid == -1) {
|
if ($pid == -1) {
|
||||||
throw new Exception('Could not fork');
|
throw new IcingaException('Could not fork');
|
||||||
} else if ($pid) {
|
} else if ($pid) {
|
||||||
echo $this->screen->colorize('[OK]')
|
echo $this->screen->colorize('[OK]')
|
||||||
. " Icinga Web server forked successfully\n";
|
. " Icinga Web server forked successfully\n";
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
use \Zend_Config;
|
|
||||||
use Icinga\Web\Url;
|
use Icinga\Web\Url;
|
||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
use Icinga\Config\PreservingIniWriter;
|
use Icinga\Config\PreservingIniWriter;
|
||||||
@ -12,6 +11,7 @@ use Icinga\Form\Dashboard\AddUrlForm;
|
|||||||
use Icinga\Exception\NotReadableError;
|
use Icinga\Exception\NotReadableError;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
use Icinga\Web\Controller\ActionController;
|
use Icinga\Web\Controller\ActionController;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle creation, removal and displaying of dashboards, panes and components
|
* Handle creation, removal and displaying of dashboards, panes and components
|
||||||
@ -42,7 +42,7 @@ class DashboardController extends ActionController
|
|||||||
}
|
}
|
||||||
$dashboard->readConfig($dashboardConfig);
|
$dashboard->readConfig($dashboardConfig);
|
||||||
} catch (NotReadableError $e) {
|
} catch (NotReadableError $e) {
|
||||||
Logger::error(new Exception('Cannot load dashboard configuration. An exception was thrown:', 0, $e));
|
Logger::error(new IcingaException('Cannot load dashboard configuration. An exception was thrown:', $e));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return $dashboard;
|
return $dashboard;
|
||||||
@ -111,7 +111,11 @@ class DashboardController extends ActionController
|
|||||||
*/
|
*/
|
||||||
public function indexAction()
|
public function indexAction()
|
||||||
{
|
{
|
||||||
$dashboard = $this->getDashboard();
|
$dashboard = Dashboard::load();
|
||||||
|
|
||||||
|
if (! $dashboard->hasPanes()) {
|
||||||
|
$this->view->title = 'Dashboard';
|
||||||
|
} else {
|
||||||
if ($this->_getParam('pane')) {
|
if ($this->_getParam('pane')) {
|
||||||
$pane = $this->_getParam('pane');
|
$pane = $this->_getParam('pane');
|
||||||
$dashboard->activate($pane);
|
$dashboard->activate($pane);
|
||||||
@ -136,7 +140,7 @@ class DashboardController extends ActionController
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$this->view->dashboard = $dashboard;
|
$this->view->dashboard = $dashboard;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
// namespace Icinga\Application\Controllers;
|
// namespace Icinga\Application\Controllers;
|
||||||
|
|
||||||
|
use Icinga\Logger\Logger;
|
||||||
use Icinga\Web\Controller\ActionController;
|
use Icinga\Web\Controller\ActionController;
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
|
|
||||||
@ -21,6 +22,10 @@ class ErrorController extends ActionController
|
|||||||
{
|
{
|
||||||
$error = $this->_getParam('error_handler');
|
$error = $this->_getParam('error_handler');
|
||||||
$exception = $error->exception;
|
$exception = $error->exception;
|
||||||
|
|
||||||
|
Logger::error($exception);
|
||||||
|
Logger::error('Stacktrace: %s', $exception->getTraceAsString());
|
||||||
|
|
||||||
switch ($error->type) {
|
switch ($error->type) {
|
||||||
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
|
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
|
||||||
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
|
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
|
||||||
|
@ -18,9 +18,12 @@ class LayoutController extends ActionController
|
|||||||
*/
|
*/
|
||||||
public function menuAction()
|
public function menuAction()
|
||||||
{
|
{
|
||||||
$this->view->menuRenderer = new MenuRenderer(
|
$this->setAutorefreshInterval(15);
|
||||||
Menu::fromConfig()->order(), Url::fromRequest()->without('renderLayout')->getRelativeUrl()
|
$this->_helper->layout()->disableLayout();
|
||||||
);
|
|
||||||
|
$url = Url::fromRequest();
|
||||||
|
$menu = new MenuRenderer(Menu::load(), $url->getRelativeUrl());
|
||||||
|
$this->view->menuRenderer = $menu->useCustomRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,11 +33,11 @@ class LayoutController extends ActionController
|
|||||||
{
|
{
|
||||||
$topbarHtmlParts = array();
|
$topbarHtmlParts = array();
|
||||||
|
|
||||||
/** @var Hook\Layout\TopBar $hook */
|
/** @var Hook\TopBarHook $hook */
|
||||||
$hook = null;
|
$hook = null;
|
||||||
|
|
||||||
foreach (Hook::all('TopBar') as $hook) {
|
foreach (Hook::all('TopBar') as $hook) {
|
||||||
$topbarHtmlParts[] = $hook->getHtml($this->getRequest(), $this->view);
|
$topbarHtmlParts[] = $hook->getHtml($this->getRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->view->topbarHtmlParts = $topbarHtmlParts;
|
$this->view->topbarHtmlParts = $topbarHtmlParts;
|
||||||
|
@ -4,9 +4,12 @@
|
|||||||
|
|
||||||
use Icinga\Module\Monitoring\Controller;
|
use Icinga\Module\Monitoring\Controller;
|
||||||
use Icinga\Web\Hook;
|
use Icinga\Web\Hook;
|
||||||
use Icinga\Application\Config as IcingaConfig;
|
|
||||||
use Icinga\Web\Url;
|
use Icinga\Web\Url;
|
||||||
use Icinga\Data\ResourceFactory;
|
use Icinga\Data\ResourceFactory;
|
||||||
|
use Icinga\Logger\Logger;
|
||||||
|
use Icinga\Logger\Writer\FileWriter;
|
||||||
|
use Icinga\Protocol\File\FileReader;
|
||||||
|
use \Zend_Controller_Action_Exception as ActionError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ListController
|
* Class ListController
|
||||||
@ -36,20 +39,21 @@ class ListController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function applicationlogAction()
|
public function applicationlogAction()
|
||||||
{
|
{
|
||||||
$this->addTitleTab('application log');
|
if (! Logger::writesToFile()) {
|
||||||
$config_ini = IcingaConfig::app()->toArray();
|
throw new ActionError('Site not found', 404);
|
||||||
if (!in_array('logging', $config_ini) || (
|
|
||||||
in_array('type', $config_ini['logging']) &&
|
|
||||||
$config_ini['logging']['type'] === 'file' &&
|
|
||||||
in_array('target', $config_ini['logging']) &&
|
|
||||||
file_exists($config_ini['logging']['target'])
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
$config = ResourceFactory::getResourceConfig('logfile');
|
|
||||||
$resource = ResourceFactory::createResource($config);
|
|
||||||
$this->view->logData = $resource->select()->order('DESC')->paginate();
|
|
||||||
} else {
|
|
||||||
$this->view->logData = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->addTitleTab('application log');
|
||||||
|
$pattern = '/^(?<datetime>[0-9]{4}(-[0-9]{2}){2}' // date
|
||||||
|
. 'T[0-9]{2}(:[0-9]{2}){2}([\\+\\-][0-9]{2}:[0-9]{2})?)' // time
|
||||||
|
. ' - (?<loglevel>[A-Za-z]+)' // loglevel
|
||||||
|
. ' - (?<message>.*)$/'; // message
|
||||||
|
|
||||||
|
$loggerWriter = Logger::getInstance()->getWriter();
|
||||||
|
$resource = new FileReader(new Zend_Config(array(
|
||||||
|
'filename' => $loggerWriter->getPath(),
|
||||||
|
'fields' => $pattern
|
||||||
|
)));
|
||||||
|
$this->view->logData = $resource->select()->order('DESC')->paginate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
use Icinga\Web\Controller\ActionController;
|
use Icinga\Web\Controller\ActionController;
|
||||||
use Icinga\Application\Icinga;
|
|
||||||
use Icinga\Web\Widget;
|
use Icinga\Web\Widget;
|
||||||
use Icinga\Web\Url;
|
use Icinga\Web\Widget\SearchDashboard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search controller
|
* Search controller
|
||||||
@ -14,47 +13,13 @@ class SearchController extends ActionController
|
|||||||
{
|
{
|
||||||
public function indexAction()
|
public function indexAction()
|
||||||
{
|
{
|
||||||
$search = $this->_request->getParam('q');
|
$this->view->dashboard = SearchDashboard::search($this->params->get('q'));
|
||||||
if (! $search) {
|
|
||||||
$this->view->tabs = Widget::create('tabs')->add(
|
// NOTE: This renders the dashboard twice. Remove this once we can catch exceptions thrown in view scripts.
|
||||||
'search',
|
$this->view->dashboard->render();
|
||||||
array(
|
|
||||||
'title' => $this->translate('Search'),
|
|
||||||
'url' => '/search',
|
|
||||||
)
|
|
||||||
)->activate('search');
|
|
||||||
$this->render('hint');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
$dashboard = Widget::create('dashboard')->createPane($this->translate('Search'));
|
|
||||||
$pane = $dashboard->getPane($this->translate('Search'));
|
public function hintAction()
|
||||||
$suffix = strlen($search) ? ': ' . rtrim($search, '*') . '*' : '';
|
{
|
||||||
$pane->addComponent(
|
|
||||||
$this->translate('Hosts') . $suffix,
|
|
||||||
Url::fromPath('monitoring/list/hosts', array(
|
|
||||||
'host_name' => $search . '*',
|
|
||||||
'sort' => 'host_severity',
|
|
||||||
'limit' => 10,
|
|
||||||
)
|
|
||||||
));
|
|
||||||
$pane->addComponent(
|
|
||||||
$this->translate('Services') . $suffix,
|
|
||||||
Url::fromPath('monitoring/list/services', array(
|
|
||||||
'service_description' => $search . '*',
|
|
||||||
'sort' => 'service_severity',
|
|
||||||
'limit' => 10,
|
|
||||||
)
|
|
||||||
));
|
|
||||||
$pane->addComponent('Hostgroups' . $suffix, Url::fromPath('monitoring/list/hostgroups', array(
|
|
||||||
'hostgroup' => $search . '*',
|
|
||||||
'limit' => 10,
|
|
||||||
)));
|
|
||||||
$pane->addComponent('Servicegroups' . $suffix, Url::fromPath('monitoring/list/servicegroups', array(
|
|
||||||
'servicegroup' => $search . '*',
|
|
||||||
'limit' => 10,
|
|
||||||
)));
|
|
||||||
$dashboard->activate($this->translate('Search'));
|
|
||||||
$this->view->dashboard = $dashboard;
|
|
||||||
$this->view->tabs = $dashboard->getTabs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
use \Zend_Controller_Action_Exception as ActionException;
|
|
||||||
use Icinga\Web\Controller\ActionController;
|
use Icinga\Web\Controller\ActionController;
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
|
use Icinga\Web\FileCache;
|
||||||
|
use Zend_Controller_Action_Exception as ActionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delivery static content to clients
|
* Delivery static content to clients
|
||||||
@ -30,8 +31,25 @@ class StaticController extends ActionController
|
|||||||
|
|
||||||
public function gravatarAction()
|
public function gravatarAction()
|
||||||
{
|
{
|
||||||
|
$cache = FileCache::instance();
|
||||||
|
$filename = md5(strtolower(trim($this->_request->getParam('email'))));
|
||||||
|
$cacheFile = 'gravatar-' . $filename;
|
||||||
|
header('Cache-Control: public');
|
||||||
|
header('Pragma: cache');
|
||||||
|
if ($etag = $cache->etagMatchesCachedFile($cacheFile)) {
|
||||||
|
header("HTTP/1.1 304 Not Modified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
header('Content-Type: image/jpg');
|
header('Content-Type: image/jpg');
|
||||||
$img = file_get_contents('http://www.gravatar.com/avatar/' . md5(strtolower(trim($this->_request->getParam('email')))) . '?s=200&d=mm');
|
if ($cache->has($cacheFile)) {
|
||||||
|
header('ETag: "' . $cache->etagForCachedFile($cacheFile) . '"');
|
||||||
|
$cache->send($cacheFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$img = file_get_contents('http://www.gravatar.com/avatar/' . $filename . '?s=120&d=mm');
|
||||||
|
$cache->store($cacheFile, $img);
|
||||||
|
header('ETag: "' . $cache->etagForCachedFile($cacheFile) . '"');
|
||||||
echo $img;
|
echo $img;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,13 +59,12 @@ class StaticController extends ActionController
|
|||||||
public function imgAction()
|
public function imgAction()
|
||||||
{
|
{
|
||||||
$module = $this->_getParam('module_name');
|
$module = $this->_getParam('module_name');
|
||||||
// TODO: This is more than dangerous, must be fixed!!
|
|
||||||
$file = $this->_getParam('file');
|
$file = $this->_getParam('file');
|
||||||
|
|
||||||
$basedir = Icinga::app()->getModuleManager()->getModule($module)->getBaseDir();
|
$basedir = Icinga::app()->getModuleManager()->getModule($module)->getBaseDir();
|
||||||
|
|
||||||
$filePath = $basedir . '/public/img/' . $file;
|
$filePath = realpath($basedir . '/public/img/' . $file);
|
||||||
if (! file_exists($filePath)) {
|
|
||||||
|
if (! $filePath || strpos($filePath, $basedir) !== 0) {
|
||||||
throw new ActionException(sprintf(
|
throw new ActionException(sprintf(
|
||||||
'%s does not exist',
|
'%s does not exist',
|
||||||
$filePath
|
$filePath
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
namespace Icinga\Form\Config\Authentication;
|
namespace Icinga\Form\Config\Authentication;
|
||||||
|
|
||||||
use \Zend_Config;
|
use Zend_Config;
|
||||||
use \Zend_Form_Element_Checkbox;
|
use Zend_Form_Element_Checkbox;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Data\ResourceFactory;
|
use Icinga\Data\ResourceFactory;
|
||||||
use Icinga\Web\Form\Decorator\HelpText;
|
use Icinga\Web\Form\Decorator\HelpText;
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
namespace Icinga\Form\Config\Authentication;
|
namespace Icinga\Form\Config\Authentication;
|
||||||
|
|
||||||
use \Exception;
|
use Exception;
|
||||||
use \Zend_Config;
|
use Zend_Config;
|
||||||
use Icinga\Data\ResourceFactory;
|
use Icinga\Data\ResourceFactory;
|
||||||
use Icinga\Authentication\DbConnection;
|
use Icinga\Authentication\DbConnection;
|
||||||
use Icinga\Authentication\Backend\DbUserBackend;
|
use Icinga\Authentication\Backend\DbUserBackend;
|
||||||
@ -111,10 +111,9 @@ class DbBackendForm extends BaseBackendForm
|
|||||||
public function isValidAuthenticationBackend()
|
public function isValidAuthenticationBackend()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$testConnection = ResourceFactory::createResource(ResourceFactory::getResourceConfig(
|
$dbUserBackend = new DbUserBackend(ResourceFactory::create(
|
||||||
$this->getValue('backend_' . $this->filterName($this->getBackendName()) . '_resource')
|
$this->getValue('backend_' . $this->filterName($this->getBackendName()) . '_resource')
|
||||||
));
|
));
|
||||||
$dbUserBackend = new DbUserBackend($testConnection);
|
|
||||||
if ($dbUserBackend->count() < 1) {
|
if ($dbUserBackend->count() < 1) {
|
||||||
$this->addErrorMessage(t("No users found under the specified database backend"));
|
$this->addErrorMessage(t("No users found under the specified database backend"));
|
||||||
return false;
|
return false;
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
namespace Icinga\Form\Config\Authentication;
|
namespace Icinga\Form\Config\Authentication;
|
||||||
|
|
||||||
use \Exception;
|
use Exception;
|
||||||
use \Zend_Config;
|
use Icinga\Application\Platform;
|
||||||
|
use Zend_Config;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Data\ResourceFactory;
|
use Icinga\Data\ResourceFactory;
|
||||||
use Icinga\Authentication\Backend\LdapUserBackend;
|
use Icinga\Authentication\Backend\LdapUserBackend;
|
||||||
@ -135,7 +136,7 @@ class LdapBackendForm extends BaseBackendForm
|
|||||||
*/
|
*/
|
||||||
public function isValidAuthenticationBackend()
|
public function isValidAuthenticationBackend()
|
||||||
{
|
{
|
||||||
if (! ResourceFactory::ldapAvailable()) {
|
if (! Platform::extensionLoaded('ldap')) {
|
||||||
/*
|
/*
|
||||||
* It should be possible to run icingaweb without the php ldap extension, when
|
* It should be possible to run icingaweb without the php ldap extension, when
|
||||||
* no ldap backends are needed. When the user tries to create an ldap backend
|
* no ldap backends are needed. When the user tries to create an ldap backend
|
||||||
@ -148,7 +149,7 @@ class LdapBackendForm extends BaseBackendForm
|
|||||||
$cfg = $this->getConfig();
|
$cfg = $this->getConfig();
|
||||||
$backendName = 'backend_' . $this->filterName($this->getBackendName()) . '_name';
|
$backendName = 'backend_' . $this->filterName($this->getBackendName()) . '_name';
|
||||||
$backendConfig = new Zend_Config($cfg[$this->getValue($backendName)]);
|
$backendConfig = new Zend_Config($cfg[$this->getValue($backendName)]);
|
||||||
$backend = ResourceFactory::createResource(ResourceFactory::getResourceConfig($backendConfig->resource));
|
$backend = ResourceFactory::create($backendConfig->resource);
|
||||||
$testConn = new LdapUserBackend(
|
$testConn = new LdapUserBackend(
|
||||||
$backend,
|
$backend,
|
||||||
$backendConfig->user_class,
|
$backendConfig->user_class,
|
||||||
@ -157,7 +158,7 @@ class LdapBackendForm extends BaseBackendForm
|
|||||||
$testConn->assertAuthenticationPossible();
|
$testConn->assertAuthenticationPossible();
|
||||||
/*
|
/*
|
||||||
if ($testConn->count() === 0) {
|
if ($testConn->count() === 0) {
|
||||||
throw new Exception('No Users Found On Directory Server');
|
throw new IcingaException('No Users Found On Directory Server');
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Form\Config\Authentication;
|
namespace Icinga\Form\Config\Authentication;
|
||||||
|
|
||||||
use \Zend_Config;
|
use Zend_Config;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Form\Config;
|
namespace Icinga\Form\Config;
|
||||||
|
|
||||||
use \Zend_Config;
|
use Zend_Config;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Web\Form\Validator\WritablePathValidator;
|
use Icinga\Web\Form\Validator\WritablePathValidator;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
namespace Icinga\Form\Config;
|
namespace Icinga\Form\Config;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Icinga\Application\Platform;
|
||||||
use Zend_Config;
|
use Zend_Config;
|
||||||
use Zend_Form_Element_Checkbox;
|
use Zend_Form_Element_Checkbox;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
@ -405,14 +406,14 @@ class ResourceForm extends Form
|
|||||||
* in case they aren't actually used. When the user tries to create a resource that depends on an
|
* in case they aren't actually used. When the user tries to create a resource that depends on an
|
||||||
* uninstalled extension, an error should be displayed.
|
* uninstalled extension, an error should be displayed.
|
||||||
*/
|
*/
|
||||||
if ($config->db === 'mysql' && !ResourceFactory::mysqlAvailable()) {
|
if ($config->db === 'mysql' && ! Platform::extensionLoaded('mysql')) {
|
||||||
$this->addErrorMessage(
|
$this->addErrorMessage(
|
||||||
t('You need to install the php extension "mysql" and the ' .
|
t('You need to install the php extension "mysql" and the ' .
|
||||||
'Zend_Pdo_Mysql classes to use MySQL database resources.')
|
'Zend_Pdo_Mysql classes to use MySQL database resources.')
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($config->db === 'pgsql' && !ResourceFactory::pgsqlAvailable()) {
|
if ($config->db === 'pgsql' && ! Platform::extensionLoaded('pgsql')) {
|
||||||
$this->addErrorMessage(
|
$this->addErrorMessage(
|
||||||
t('You need to install the php extension "pgsql" and the ' .
|
t('You need to install the php extension "pgsql" and the ' .
|
||||||
'Zend_Pdo_Pgsql classes to use PostgreSQL database resources.')
|
'Zend_Pdo_Pgsql classes to use PostgreSQL database resources.')
|
||||||
|
@ -4,15 +4,16 @@
|
|||||||
|
|
||||||
namespace Icinga\Form\Preference;
|
namespace Icinga\Form\Preference;
|
||||||
|
|
||||||
use \DateTimeZone;
|
use DateTimeZone;
|
||||||
use \Zend_Config;
|
use Icinga\Util\TimezoneDetect;
|
||||||
use \Zend_Form_Element_Text;
|
use Zend_Config;
|
||||||
use \Zend_Form_Element_Select;
|
use Zend_Form_Element_Text;
|
||||||
use \Zend_View_Helper_DateFormat;
|
use Zend_Form_Element_Select;
|
||||||
use \Icinga\Web\Form;
|
use Zend_View_Helper_DateFormat;
|
||||||
use \Icinga\Web\Form\Validator\TimeFormatValidator;
|
use Icinga\Web\Form;
|
||||||
use \Icinga\Web\Form\Validator\DateFormatValidator;
|
use Icinga\Web\Form\Validator\TimeFormatValidator;
|
||||||
use \Icinga\Util\Translator;
|
use Icinga\Web\Form\Validator\DateFormatValidator;
|
||||||
|
use Icinga\Util\Translator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General user preferences
|
* General user preferences
|
||||||
@ -69,13 +70,22 @@ class GeneralForm extends Form
|
|||||||
*/
|
*/
|
||||||
private function addTimezoneSelection(Zend_Config $cfg)
|
private function addTimezoneSelection(Zend_Config $cfg)
|
||||||
{
|
{
|
||||||
|
$prefs = $this->getUserPreferences();
|
||||||
|
$useGlobalTimezone = $this->getRequest()->getParam('default_timezone', !$prefs->has('app.timezone'));
|
||||||
|
$detect = new TimezoneDetect();
|
||||||
|
|
||||||
$tzList = array();
|
$tzList = array();
|
||||||
foreach (DateTimeZone::listIdentifiers() as $tz) {
|
foreach (DateTimeZone::listIdentifiers() as $tz) {
|
||||||
$tzList[$tz] = $tz;
|
$tzList[$tz] = $tz;
|
||||||
}
|
}
|
||||||
|
|
||||||
$helptext = 'Use the following timezone for dates and times';
|
$helptext = 'Use the following timezone for dates and times';
|
||||||
$prefs = $this->getUserPreferences();
|
|
||||||
$useGlobalTimezone = $this->getRequest()->getParam('default_timezone', !$prefs->has('app.timezone'));
|
if ($useGlobalTimezone && $detect->success() === true) {
|
||||||
|
$helptext .= '<br />' . t('Currently your time was detected to be')
|
||||||
|
. ': '
|
||||||
|
. '<strong>' . $detect->getTimezoneName() . '</strong>';
|
||||||
|
}
|
||||||
|
|
||||||
$selectTimezone = new Zend_Form_Element_Select(
|
$selectTimezone = new Zend_Form_Element_Select(
|
||||||
array(
|
array(
|
||||||
@ -87,6 +97,7 @@ class GeneralForm extends Form
|
|||||||
'value' => $prefs->get('app.timezone', $cfg->get('timezone', date_default_timezone_get()))
|
'value' => $prefs->get('app.timezone', $cfg->get('timezone', date_default_timezone_get()))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
'checkbox',
|
'checkbox',
|
||||||
'default_timezone',
|
'default_timezone',
|
||||||
@ -99,7 +110,9 @@ class GeneralForm extends Form
|
|||||||
if ($useGlobalTimezone) {
|
if ($useGlobalTimezone) {
|
||||||
$selectTimezone->setAttrib('disabled', 1);
|
$selectTimezone->setAttrib('disabled', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addElement($selectTimezone);
|
$this->addElement($selectTimezone);
|
||||||
|
|
||||||
$this->enableAutoSubmit(array('default_timezone'));
|
$this->enableAutoSubmit(array('default_timezone'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,17 +29,17 @@ $iframeClass = $isIframe ? ' iframe' : '';
|
|||||||
<title><?= $this->title ? $this->escape($this->title) : 'Icinga Web' ?></title>
|
<title><?= $this->title ? $this->escape($this->title) : 'Icinga Web' ?></title>
|
||||||
<!-- TODO: viewport and scale settings make no sense for us, fix this -->
|
<!-- TODO: viewport and scale settings make no sense for us, fix this -->
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<link rel="stylesheet" href="<?= $this->href($cssfile) ?>" media="screen" type="text/css" />
|
<? if ($isIframe): ?>
|
||||||
<? if ($isIframe): ?>
|
|
||||||
<base target="_parent"/>
|
<base target="_parent"/>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function() {
|
(function() {
|
||||||
var html = document.getElementsByTagName('html')[0];
|
var html = document.getElementsByTagName('html')[0];
|
||||||
html.className = html.className.replace(/no-js/, 'js');
|
html.className = html.className.replace(/no-js/, 'js');
|
||||||
}());
|
}());
|
||||||
</script>
|
</script>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
<link rel="stylesheet" href="<?= $this->href($cssfile) ?>" media="screen" type="text/css" />
|
||||||
<!-- Respond.js IE8 support of media queries -->
|
<!-- Respond.js IE8 support of media queries -->
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
<script src="<?= $this->baseUrl('js/vendor/respond.min.js');?>"></script>
|
<script src="<?= $this->baseUrl('js/vendor/respond.min.js');?>"></script>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use Icinga\Web\Url;
|
use Icinga\Web\Url;
|
||||||
use Icinga\Web\Menu;
|
use Icinga\Web\Menu;
|
||||||
use Icinga\Web\MenuRenderer;
|
use Icinga\Web\MenuRenderer;
|
||||||
|
use Icinga\Web\Widget\SearchDashboard;
|
||||||
|
|
||||||
// Don't render a menu for unauthenticated users unless menu is auth aware
|
// Don't render a menu for unauthenticated users unless menu is auth aware
|
||||||
if (! $this->auth()->isAuthenticated()) {
|
if (! $this->auth()->isAuthenticated()) {
|
||||||
@ -10,9 +11,15 @@ if (! $this->auth()->isAuthenticated()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div id="menu" data-base-target="_main">
|
<div
|
||||||
|
id="menu" data-last-update="<?= (time() - 14) ?>000" data-base-target="_main" class="container" data-icinga-url="<?=$this->href('layout/menu');?>"
|
||||||
|
data-icinga-refresh="15"
|
||||||
|
>
|
||||||
|
<? if (SearchDashboard::search('dummy')->getPane('search')->hasComponents()): ?>
|
||||||
<form action="<?= $this->href('search') ?>" method="get" role="search">
|
<form action="<?= $this->href('search') ?>" method="get" role="search">
|
||||||
<input type="text" name="q" class="search autofocus" placeholder="<?= $this->translate('Search...') ?>" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
|
<input type="text" name="q" class="search autofocus" placeholder="<?= $this->translate('Search...') ?>"
|
||||||
|
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
|
||||||
</form>
|
</form>
|
||||||
<?= new MenuRenderer(Menu::fromConfig()->order(), Url::fromRequest()->without('renderLayout')->getRelativeUrl()); ?>
|
<? endif; ?>
|
||||||
|
<?= new MenuRenderer(Menu::load(), Url::fromRequest()->without('renderLayout')->getRelativeUrl()); ?>
|
||||||
</div>
|
</div>
|
||||||
|
Binary file not shown.
@ -5,121 +5,191 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Icinga Web 2 (0.1)\n"
|
"Project-Id-Version: Icinga Web 2 (None)\n"
|
||||||
"Report-Msgid-Bugs-To: dev@icinga.org\n"
|
"Report-Msgid-Bugs-To: dev@icinga.org\n"
|
||||||
"POT-Creation-Date: 2014-05-29 11:12+0000\n"
|
"POT-Creation-Date: 2014-08-22 17:30+0200\n"
|
||||||
"PO-Revision-Date: 2014-05-29 13:19+0100\n"
|
"PO-Revision-Date: 2014-08-22 17:52+0100\n"
|
||||||
"Last-Translator: Thomas Gelf <thomas@gelf.net>\n"
|
"Last-Translator: Thomas Gelf <thomas@gelf.net>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:15
|
|
||||||
#, php-format
|
|
||||||
msgid "%d to %d of %d"
|
|
||||||
msgstr "%d bis %d von %d"
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/pivottablePagination.phtml:9
|
#: /usr/local/src/bugfix.master/application/views/scripts/pivottablePagination.phtml:9
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%s: %d to %d of %d"
|
msgid "%s: %d to %d of %d"
|
||||||
msgstr "%s: %d bis %d von %d"
|
msgstr "%s: %d bis %d von %d"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:117
|
#: /usr/local/src/bugfix.master/application/forms/Authentication/LoginForm.php:36
|
||||||
|
msgid "...and your password"
|
||||||
|
msgstr "...und dein Kennwort ein"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterEditor.php:132
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Hinzufügen"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterWidget.php:81
|
||||||
|
msgid "Add filter..."
|
||||||
|
msgstr "Filter hinzufügen..."
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:118
|
||||||
|
msgid "All configured authentication methods failed. Please check the system log or Icinga Web 2 log for more information."
|
||||||
|
msgstr "Alle konfigurierten Authentifizierungsmethoden sind fehlgeschlagen. Bitte überprüfe das Systemlog oder jenes von Icinga Web 2 für weitere Details."
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:91
|
||||||
msgid "Application Prefix"
|
msgid "Application Prefix"
|
||||||
msgstr "Anwendungspräfix"
|
msgstr "Anwendungspräfix"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:78
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Menu.php:197
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:80
|
msgid "ApplicationLog"
|
||||||
|
msgstr "Anwendungslog"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Form/notyet_FormWizard.php:31
|
||||||
|
msgid "Back"
|
||||||
|
msgstr "Zurück"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:53
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:55
|
||||||
msgid "Backend Name"
|
msgid "Backend Name"
|
||||||
msgstr "Backend-Name"
|
msgstr "Backend-Name"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:282
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:257
|
||||||
msgid "Bind DN"
|
msgid "Bind DN"
|
||||||
msgstr "Bind DN"
|
msgstr "Bind DN"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:294
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:269
|
||||||
msgid "Bind Password"
|
msgid "Bind Password"
|
||||||
msgstr "Bind Kennwort"
|
msgstr "Bind Kennwort"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:358
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:333
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/BaseBackendForm.php:139
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/BaseBackendForm.php:114
|
||||||
msgid "Check this box to enforce changes without connectivity validation"
|
msgid "Check this box to enforce changes without connectivity validation"
|
||||||
msgstr "Aktiviere dieses Häkchen um die Änderungen ohne Validierung der Verbindung zu speichern"
|
msgstr "Aktiviere dieses Häkchen um die Änderungen ohne Validierung der Verbindung zu speichern"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:73
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:47
|
||||||
msgid "Check this to enable logging."
|
msgid "Check this to enable logging."
|
||||||
msgstr "Aktiviere dieses Häkchen um das Logging zu aktivieren."
|
msgstr "Aktiviere dieses Häkchen um das Logging zu aktivieren."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:187
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterEditor.php:108
|
||||||
|
msgid "Click to add a filter expression to this operator"
|
||||||
|
msgstr "Hier klicken, um einen Filter-Ausdruck zu diesem Operator hinzuzufügen"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterEditor.php:105
|
||||||
|
msgid "Click to add another operator below this one"
|
||||||
|
msgstr "Hier klicken, um unterhalb dieses Operators einen weiteren hinzuzufügen"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterEditor.php:97
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterWidget.php:69
|
||||||
|
msgid "Click to remove this part of your filter"
|
||||||
|
msgstr "Klicken, um diesen Teil des Filters zu löschen"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Menu.php:189
|
||||||
|
msgid "Configuration"
|
||||||
|
msgstr "Konfiguration"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:165
|
||||||
msgid "Connection Validation Failed: "
|
msgid "Connection Validation Failed: "
|
||||||
msgstr "Überprüfung der Verbindung fehlgeschlagen: "
|
msgstr "Überprüfung der Verbindung fehlgeschlagen: "
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:477
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:452
|
||||||
msgid "Connectivity validation failed, connection to the given resource not possible."
|
msgid "Connectivity validation failed, connection to the given resource not possible."
|
||||||
msgstr "Überprüfung fehlgeschlagen, konnte keine Verbindung zu der angegebenen Ressource herstellen."
|
msgstr "Überprüfung fehlgeschlagen, konnte keine Verbindung zu der angegebenen Ressource herstellen."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:454
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:429
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:470
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:445
|
||||||
msgid "Connectivity validation failed, the provided file does not exist."
|
msgid "Connectivity validation failed, the provided file does not exist."
|
||||||
msgstr "Überprüfung fehlgeschlagen, die angegebene Datei existiert nicht."
|
msgstr "Überprüfung fehlgeschlagen, die angegebene Datei existiert nicht."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:90
|
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:59
|
||||||
|
msgid "Could not read your authentiction.ini, no authentication methods are available."
|
||||||
|
msgstr "Deine authentication.ini konnte nicht gelesen werden, darum sind keine Authentifizierungsmethoden verfügbar."
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/layouts/scripts/body.phtml:31
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Menu.php:175
|
||||||
|
msgid "Dashboard"
|
||||||
|
msgstr "Dashboard"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:65
|
||||||
msgid "Database Connection"
|
msgid "Database Connection"
|
||||||
msgstr "Datenbankverbindung"
|
msgstr "Datenbankverbindung"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:183
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:158
|
||||||
msgid "Database Name"
|
msgid "Database Name"
|
||||||
msgstr "Datenbankname"
|
msgstr "Datenbankname"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:144
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:119
|
||||||
msgid "Database Type"
|
msgid "Database Type"
|
||||||
msgstr "Datenbanktyp"
|
msgstr "Datenbanktyp"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:89
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:63
|
||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr "Debug"
|
msgstr "Debug"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/GeneralForm.php:185
|
#: /usr/local/src/bugfix.master/application/forms/Config/GeneralForm.php:101
|
||||||
msgid "Default Language"
|
msgid "Default Language"
|
||||||
msgstr "Standardsprache"
|
msgstr "Standardsprache"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/controllers/ErrorController.php:62
|
#: /usr/local/src/bugfix.master/application/controllers/ErrorController.php:36
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Enabling the \"%s\" module might help!"
|
msgid "Enabling the \"%s\" module might help!"
|
||||||
msgstr "Das Modul \"%s\" zu aktivieren könnte helfen!"
|
msgstr "Das Modul \"%s\" zu aktivieren könnte helfen!"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:86
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:60
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Fehler"
|
msgstr "Fehler"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:139
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterEditor.php:109
|
||||||
|
msgid "Expression"
|
||||||
|
msgstr "Ausdruck"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:113
|
||||||
msgid "Facility"
|
msgid "Facility"
|
||||||
msgstr "Facility"
|
msgstr "Facility"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:102
|
#: /usr/local/src/bugfix.master/application/controllers/PreferenceController.php:55
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:383
|
#, php-format
|
||||||
|
msgid "Failed to persist preferences. (%s)"
|
||||||
|
msgstr "Persistierung der Einstellungen fehlgeschlagen. (%s)"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:76
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:358
|
||||||
msgid "File"
|
msgid "File"
|
||||||
msgstr "Datei"
|
msgstr "Datei"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:155
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:129
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:220
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:195
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:231
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:206
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:308
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:283
|
||||||
msgid "Filepath"
|
msgid "Filepath"
|
||||||
msgstr "Dateipfad"
|
msgstr "Dateipfad"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:357
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterWidget.php:90
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/BaseBackendForm.php:138
|
msgid "Filter this list"
|
||||||
|
msgstr "Diese Liste filtern"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterWidget.php:94
|
||||||
|
msgid "Filtered"
|
||||||
|
msgstr "Gefiltert"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Form/notyet_FormWizard.php:32
|
||||||
|
msgid "Finish"
|
||||||
|
msgstr "Fertigstellen"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:332
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/BaseBackendForm.php:113
|
||||||
msgid "Force Changes"
|
msgid "Force Changes"
|
||||||
msgstr "Änderungen erzwingen"
|
msgstr "Änderungen erzwingen"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Form/notyet_QuickForm.php:147
|
||||||
|
msgid "Form has successfully been sent"
|
||||||
|
msgstr "Das Formular wurde erfolgreich versendet"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/search/hint.phtml:7
|
#: /usr/local/src/bugfix.master/application/views/scripts/search/hint.phtml:7
|
||||||
msgid "Hint"
|
msgid "Hint"
|
||||||
msgstr "Hinweis"
|
msgstr "Hinweis"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:160
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:135
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:260
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:235
|
||||||
msgid "Host"
|
msgid "Host"
|
||||||
msgstr "Host"
|
msgstr "Host"
|
||||||
|
|
||||||
@ -132,165 +202,183 @@ msgstr "Hosts"
|
|||||||
msgid "I'm ready to search, waiting for your input"
|
msgid "I'm ready to search, waiting for your input"
|
||||||
msgstr "Ich bin bereit zur Suche, warte auf deine Eingabe"
|
msgstr "Ich bin bereit zur Suche, warte auf deine Eingabe"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:63
|
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:40
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/login.phtml:8
|
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/login.phtml:8
|
||||||
msgid "Icingaweb Login"
|
msgid "Icingaweb Login"
|
||||||
msgstr "Icingaweb Anmeldung"
|
msgstr "Icingaweb Anmeldung"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:17
|
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:14
|
||||||
msgid "If this message does not disappear, it might be necessary to quit the current session manually by clearing the cache, or by closing the current browser session."
|
msgid "If this message does not disappear, it might be necessary to quit the current session manually by clearing the cache, or by closing the current browser session."
|
||||||
msgstr "Wenn diese Nachricht nicht verschwindet könnte es nötig sein die aktuelle Sitzung manuell zu beenden indem der Cache gelöscht order die Browsersitzung geschlossen wird."
|
msgstr "Wenn diese Nachricht nicht verschwindet könnte es nötig sein die aktuelle Sitzung manuell zu beenden indem der Cache gelöscht order die Browsersitzung geschlossen wird."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:118
|
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:131
|
||||||
msgid "Incorrect username or password"
|
msgid "Incorrect username or password"
|
||||||
msgstr "Benutzername oder Kennwort ungültig"
|
msgstr "Benutzername oder Kennwort ungültig"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:88
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:62
|
||||||
msgid "Information"
|
msgid "Information"
|
||||||
msgstr "Information"
|
msgstr "Information"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Web/Wizard/Wizard.php:337
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:67
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Web/Wizard/Wizard.php:380
|
|
||||||
msgid "Install"
|
|
||||||
msgstr "Installieren"
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/install/index.phtml:29
|
|
||||||
msgid "Installation"
|
|
||||||
msgstr "Installation"
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:92
|
|
||||||
msgid "LDAP Resource"
|
msgid "LDAP Resource"
|
||||||
msgstr "LDAP Ressource"
|
msgstr "LDAP Ressource"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:115
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:90
|
||||||
msgid "LDAP User Name Attribute"
|
msgid "LDAP User Name Attribute"
|
||||||
msgstr "LDAP-Attribut für Benutzername"
|
msgstr "LDAP-Attribut für Benutzername"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:104
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:79
|
||||||
msgid "LDAP User Object Class"
|
msgid "LDAP User Object Class"
|
||||||
msgstr "LDAP Objektklasse für Benutzer"
|
msgstr "LDAP Objektklasse für Benutzer"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:232
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:207
|
||||||
msgid "Location of your icinga objects.cache file"
|
msgid "Location of your icinga objects.cache file"
|
||||||
msgstr "Pfad zur Datei objects.cache von Icinga"
|
msgstr "Pfad zur Datei objects.cache von Icinga"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:221
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:196
|
||||||
msgid "Location of your icinga status.dat file"
|
msgid "Location of your icinga status.dat file"
|
||||||
msgstr "Pfad zur Datei status.dat von Icinga"
|
msgstr "Pfad zur Datei status.dat von Icinga"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/controllers/InstallController.php:69
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:46
|
||||||
msgid "Logging"
|
|
||||||
msgstr "Logging"
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:72
|
|
||||||
msgid "Logging Enabled"
|
msgid "Logging Enabled"
|
||||||
msgstr "Logging aktiv"
|
msgstr "Logging aktiv"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:82
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:56
|
||||||
msgid "Logging Level"
|
msgid "Logging Level"
|
||||||
msgstr "Log-Level"
|
msgstr "Log-Level"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:98
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:72
|
||||||
msgid "Logging Type"
|
msgid "Logging Type"
|
||||||
msgstr "Logging-Typ"
|
msgstr "Logging-Typ"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:15
|
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:12
|
||||||
msgid "Logging out..."
|
msgid "Logging out..."
|
||||||
msgstr "Abmelden..."
|
msgstr "Abmelden..."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:28
|
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:21
|
||||||
msgid "Login"
|
msgid "Login"
|
||||||
msgstr "Anmelden"
|
msgstr "Anmelden"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/layouts/scripts/body.phtml:39
|
|
||||||
#: /usr/local/src/bugfix.master/application/layouts/scripts/parts/topbar.phtml:35
|
#: /usr/local/src/bugfix.master/application/layouts/scripts/parts/topbar.phtml:35
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Menu.php:202
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Abmelden"
|
msgstr "Abmelden"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:64
|
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:43
|
||||||
msgid "Logout not possible, it may be necessary to quit the session manually by clearing the cache, or closing the current browser session. Error: "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/logout.phtml:69
|
|
||||||
msgid "Logout successful!"
|
msgid "Logout successful!"
|
||||||
msgstr "Abmelden erfolgreich!"
|
msgstr "Abmelden erfolgreich!"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/ReorderForm.php:137
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterEditor.php:235
|
||||||
msgid "Move down in authentication order"
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterWidget.php:95
|
||||||
msgstr ""
|
msgid "Modify this filter"
|
||||||
|
msgstr "Diesen Filter bearbeiten"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/ReorderForm.php:111
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Menu.php:193
|
||||||
|
msgid "Modules"
|
||||||
|
msgstr "Module"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/ReorderForm.php:112
|
||||||
|
msgid "Move down in authentication order"
|
||||||
|
msgstr "In der Authentifizierungsreihenfolge nach unten schieben"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/ReorderForm.php:86
|
||||||
msgid "Move up in authentication order"
|
msgid "Move up in authentication order"
|
||||||
msgstr ""
|
msgstr "In der Authentifizierungsreihenfolge nach oben schieben"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/pivottablePagination.phtml:16
|
#: /usr/local/src/bugfix.master/application/views/scripts/pivottablePagination.phtml:16
|
||||||
msgid "Navigation"
|
msgid "Navigation"
|
||||||
msgstr "Navigation"
|
msgstr "Navigation"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:83
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:86
|
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:86
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Web/Wizard/Wizard.php:337
|
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:89
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Web/Wizard/Wizard.php:380
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Form/notyet_FormWizard.php:30
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr "Weiter"
|
msgstr "Weiter"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:144
|
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:110
|
||||||
msgid "No users found under the specified database backend"
|
msgid "No authentication methods available. Did you create authentication.ini when installing Icinga Web 2?"
|
||||||
msgstr ""
|
msgstr "Keine Authentifizierungsmethode verfügbar. Hast du beim Installieren von Icinga Web 2 eine authentication.ini erstellt?"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/controllers/ErrorController.php:59
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:119
|
||||||
|
msgid "No users found under the specified database backend"
|
||||||
|
msgstr "Im konfigurierten Datenbankbackend wurden keine Benutzer gefunden"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterEditor.php:106
|
||||||
|
msgid "Operator"
|
||||||
|
msgstr "Operator"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:33
|
||||||
|
msgid "Page"
|
||||||
|
msgstr "Seite"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/controllers/ErrorController.php:33
|
||||||
msgid "Page not found."
|
msgid "Page not found."
|
||||||
msgstr "Seite nicht gefunden."
|
msgstr "Seite nicht gefunden."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Authentication/LoginForm.php:65
|
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:12
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:206
|
msgid "Pagination"
|
||||||
|
msgstr "Seitennavigation"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Authentication/LoginForm.php:35
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:181
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Kennwort"
|
msgstr "Kennwort"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:319
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:294
|
||||||
msgid "Pattern"
|
msgid "Pattern"
|
||||||
msgstr "Muster"
|
msgstr "Muster"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Web/Form/Element/Number.php:61
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Form/Element/Number.php:36
|
||||||
msgid "Please enter a number."
|
msgid "Please enter a number."
|
||||||
msgstr "Bitte eine Nummer eingeben."
|
msgstr "Bitte eine Nummer eingeben."
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Authentication/LoginForm.php:25
|
||||||
|
msgid "Please enter your username..."
|
||||||
|
msgstr "Bitte gib deinen Benutzernamen..."
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/controllers/AuthenticationController.php:126
|
||||||
|
msgid "Please note that not all authentication methods where available. Check the system log or Icinga Web 2 log for more information."
|
||||||
|
msgstr "Beachte bitte dass nicht alle Authentifizierungsmethoden verfügbar waren. Überprüfe das Systemlog oder jenes von Icinga Web 2 für weitere Informationen."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/search/hint.phtml:8
|
#: /usr/local/src/bugfix.master/application/views/scripts/search/hint.phtml:8
|
||||||
msgid "Please use the asterisk (*) as a placeholder for wildcard searches. For convenience I'll always add a wildcard after the last character you typed."
|
msgid "Please use the asterisk (*) as a placeholder for wildcard searches. For convenience I'll always add a wildcard after the last character you typed."
|
||||||
msgstr "Bitte benutze das Sternchen (*) als Jokerzeichen für eine Suche mit Platzhaltern. Der Einfachheit halber hänge ich immer einen Platzhalter hinter das letzte von dir getippte Zeichen."
|
msgstr "Bitte benutze das Sternchen (*) als Jokerzeichen für eine Suche mit Platzhaltern. Der Einfachheit halber hänge ich immer einen Platzhalter hinter das letzte von dir getippte Zeichen."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:171
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:146
|
||||||
msgid "Port"
|
msgid "Port"
|
||||||
msgstr "Port"
|
msgstr "Port"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/layouts/scripts/body.phtml:38
|
|
||||||
#: /usr/local/src/bugfix.master/application/layouts/scripts/parts/topbar.phtml:32
|
#: /usr/local/src/bugfix.master/application/layouts/scripts/parts/topbar.phtml:32
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Menu.php:185
|
||||||
msgid "Preferences"
|
msgid "Preferences"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:45
|
#: /usr/local/src/bugfix.master/application/controllers/PreferenceController.php:48
|
||||||
|
msgid "Preferences updated successfully"
|
||||||
|
msgstr "Einstellungen erfolgreich aktualisiert"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:48
|
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:48
|
||||||
|
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:51
|
||||||
msgid "Prev"
|
msgid "Prev"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Web/Wizard/Wizard.php:326
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/FilterWidget.php:99
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Web/Wizard/Wizard.php:367
|
msgid "Remove this filter"
|
||||||
msgid "Previous"
|
msgstr "Diesen Filter entfernen"
|
||||||
msgstr "Vorheriges"
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:333
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:308
|
||||||
msgid "Resource Name"
|
msgid "Resource Name"
|
||||||
msgstr ""
|
msgstr "Ressourcename"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:375
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:350
|
||||||
msgid "Resource Type"
|
msgid "Resource Type"
|
||||||
msgstr ""
|
msgstr "Ressourcetyp"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:271
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:246
|
||||||
msgid "Root DN"
|
msgid "Root DN"
|
||||||
msgstr "Wurzel-DN"
|
msgstr "Wurzel-DN"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:379
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:354
|
||||||
msgid "SQL Database"
|
msgid "SQL Database"
|
||||||
msgstr "SQL Datenbank"
|
msgstr "SQL Datenbank"
|
||||||
|
|
||||||
@ -301,187 +389,241 @@ msgstr "SQL Datenbank"
|
|||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Suche"
|
msgstr "Suche"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/layouts/scripts/parts/navigation.phtml:17
|
#: /usr/local/src/bugfix.master/application/layouts/scripts/parts/navigation.phtml:15
|
||||||
msgid "Search..."
|
msgid "Search..."
|
||||||
msgstr "Suche..."
|
msgstr "Suche..."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/GeneralForm.php:189
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Form/Validator/notyet_CsrfTokenValidator.php:20
|
||||||
|
msgid "Security check failed, please submit your form again"
|
||||||
|
msgstr "Sicherheitscheck fehlgeschlagen, bitte sende das Formular erneut ab"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/GeneralForm.php:105
|
||||||
msgid "Select the language to use by default. Can be overwritten by a user in his preferences."
|
msgid "Select the language to use by default. Can be overwritten by a user in his preferences."
|
||||||
msgstr ""
|
msgstr "Die zu benutzende Standard-Sprache. Kann von Benutzern in deren Einstellungen überschrieben werden."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/controllers/SearchController.php:41
|
#: /usr/local/src/bugfix.master/application/controllers/SearchController.php:41
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/pivottablePagination.phtml:34
|
#: /usr/local/src/bugfix.master/application/views/scripts/pivottablePagination.phtml:34
|
||||||
msgid "Services"
|
msgid "Services"
|
||||||
msgstr "Services"
|
msgstr "Services"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:245
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/Limiter.php:84
|
||||||
|
#, php-format
|
||||||
|
msgid "Show %s rows on one page"
|
||||||
|
msgstr "Zeige %s Zeilen pro Seite"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/views/scripts/mixedPagination.phtml:16
|
||||||
|
#, php-format
|
||||||
|
msgid "Show rows %d to %d of %d"
|
||||||
|
msgstr "Zeige die Zeilen %d bis %d von %d"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:220
|
||||||
msgid "Socket"
|
msgid "Socket"
|
||||||
msgstr ""
|
msgstr "Socket"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:140
|
#: /usr/local/src/bugfix.master/application/views/scripts/config/module.phtml:22
|
||||||
|
msgid "State"
|
||||||
|
msgstr "Status"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Menu.php:181
|
||||||
|
msgid "System"
|
||||||
|
msgstr "System"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/views/scripts/authentication/login.phtml:4
|
||||||
|
msgid "The Icinga logo"
|
||||||
|
msgstr "Das Icinga Logo"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:114
|
||||||
msgid "The Syslog facility to utilize."
|
msgid "The Syslog facility to utilize."
|
||||||
msgstr ""
|
msgstr "Die zu benutzende Syslog-Facility"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:116
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:91
|
||||||
msgid "The attribute name used for storing the user name on the ldap server"
|
msgid "The attribute name used for storing the user name on the ldap server"
|
||||||
msgstr ""
|
msgstr "Der Attributname welcher benutzt wird, um Benutzernamen auf dem LDAP-Server abzulegen"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:91
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:66
|
||||||
msgid "The database connection to use for authenticating with this provider"
|
msgid "The database connection to use for authenticating with this provider"
|
||||||
msgstr ""
|
msgstr "Die Datenbankverbindung, welche zur Authentifizierung mit diesem Provider genutzt werden soll"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:309
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:284
|
||||||
msgid "The filename to fetch information from"
|
msgid "The filename to fetch information from"
|
||||||
msgstr ""
|
msgstr "Die Datei aus welcher Informationen gelesen werden sollen"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:161
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:136
|
||||||
msgid "The hostname of the database."
|
msgid "The hostname of the database."
|
||||||
msgstr ""
|
msgstr "Der Hostname der Datenbank."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:261
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:236
|
||||||
msgid "The hostname or address of the LDAP server to use for authentication"
|
msgid "The hostname or address of the LDAP server to use for authentication"
|
||||||
msgstr ""
|
msgstr "Der Hostname oder die IP-Adresse des LDAP-Servers der zur Authentifizierung genutzt werden soll"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:156
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:130
|
||||||
msgid "The logfile to write messages to."
|
msgid "The logfile to write messages to."
|
||||||
msgstr ""
|
msgstr "Das Logfile in welches Nachrichten geschrieben werden sollen."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:83
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:57
|
||||||
msgid "The maximum loglevel to emit."
|
msgid "The maximum loglevel to emit."
|
||||||
msgstr ""
|
msgstr "Loglevel bis zu welchem Nachrichten ausgegeben werden sollen."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:118
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:92
|
||||||
msgid "The name of the application by which to prefix syslog messages."
|
msgid "The name of the application by which to prefix syslog messages."
|
||||||
msgstr ""
|
msgstr "Der Anwendungsname welcher Syslog-Nachrichten vorangestellt werden soll."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:184
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:159
|
||||||
msgid "The name of the database to use"
|
msgid "The name of the database to use"
|
||||||
msgstr ""
|
msgstr "Der Name der zu benutzenden Datenbank"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:81
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:56
|
||||||
msgid "The name of this authentication backend"
|
msgid "The name of this authentication backend"
|
||||||
msgstr ""
|
msgstr "Der Name dieses Authentifizierungsbackends"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:79
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:54
|
||||||
msgid "The name of this authentication provider"
|
msgid "The name of this authentication provider"
|
||||||
msgstr ""
|
msgstr "Der Name dieses Authentifizierungsproviders"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:105
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:80
|
||||||
msgid "The object class used for storing users on the ldap server"
|
msgid "The object class used for storing users on the ldap server"
|
||||||
msgstr ""
|
msgstr "Die Objekt-Klasse welche benutzt wird, um Benutzer auf diesem LDAP-Server abzulegen"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:207
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:182
|
||||||
msgid "The password to use for authentication"
|
msgid "The password to use for authentication"
|
||||||
msgstr ""
|
msgstr "Das Kennwort welche zur Authentifizierung benutzt werden soll"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:270
|
||||||
|
msgid "The password to use for querying the ldap server"
|
||||||
|
msgstr "Das Kennwort welches zum Abfragen des LDAP-Servers benutzt werden soll"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:221
|
||||||
|
msgid "The path to your livestatus socket used for querying monitoring data"
|
||||||
|
msgstr "Der Pfad zu deinem Live-Status Socket, über welchen Monitoring-Daten abgefragt werden sollen"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:247
|
||||||
|
msgid "The path where users can be found on the ldap server"
|
||||||
|
msgstr "Der Pfad unter welchem Benutzer auf diesem LDAP-Server gefunden werden können."
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:147
|
||||||
|
msgid "The port to use."
|
||||||
|
msgstr "Der zu benutzende Port."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:295
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:295
|
||||||
msgid "The password to use for querying the ldap server"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:246
|
|
||||||
msgid "The path to your livestatus socket used for querying monitoring data"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:272
|
|
||||||
msgid "The path where users can be found on the ldap server"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:172
|
|
||||||
msgid "The port to use."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:320
|
|
||||||
msgid "The regular expression by which to identify columns"
|
msgid "The regular expression by which to identify columns"
|
||||||
msgstr ""
|
msgstr "Der zu benutzende reguläre Ausdruck, mit welchem Spalten identifiziert werden können"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:93
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:68
|
||||||
msgid "The resource to use for authenticating with this provider"
|
msgid "The resource to use for authenticating with this provider"
|
||||||
msgstr ""
|
msgstr "Die Resource die zum Authentifizieren mit diesem Provider genutzt werden soll"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:145
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:120
|
||||||
msgid "The type of SQL database you want to create."
|
msgid "The type of SQL database you want to create."
|
||||||
msgstr ""
|
msgstr "Der Typ der zu benutzenden SQL Datenbank."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:99
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:73
|
||||||
msgid "The type of logging to utilize."
|
msgid "The type of logging to utilize."
|
||||||
msgstr ""
|
msgstr "Der Typ des zu benutzenden Loggings."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:376
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:351
|
||||||
msgid "The type of resource"
|
msgid "The type of resource"
|
||||||
msgstr ""
|
msgstr "Der Typ der Ressource"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:334
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:309
|
||||||
msgid "The unique name of this resource"
|
msgid "The unique name of this resource"
|
||||||
msgstr ""
|
msgstr "Der eindeutige Name dieser Resource"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:283
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:258
|
||||||
msgid "The user dn to use for querying the ldap server"
|
msgid "The user dn to use for querying the ldap server"
|
||||||
msgstr ""
|
msgstr "Die DN des Benutzers mit welchem dieser LDAP-Server befragt werden soll"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:195
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:170
|
||||||
msgid "The user name to use for authentication."
|
msgid "The user name to use for authentication."
|
||||||
msgstr ""
|
msgstr "Der zur Authentifizierung zu benutzende Benutzername."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/config/module.phtml:6
|
#: /usr/local/src/bugfix.master/application/views/scripts/config/module.phtml:6
|
||||||
msgid "There is no such module installed."
|
msgid "There is no such module installed."
|
||||||
msgstr "Gegenwärtig ist kein solches Modul installiert."
|
msgstr "Gegenwärtig ist kein solches Modul installiert."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/views/scripts/config/module.phtml:32
|
#: /usr/local/src/bugfix.master/application/views/scripts/config/module.phtml:46
|
||||||
msgid "This module has no dependencies"
|
msgid "This module has no dependencies"
|
||||||
msgstr "Dieses Modul hat keine Abhängigkeiten"
|
msgstr "Dieses Modul hat keine Abhängigkeiten"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Application/Modules/Module.php:383
|
#: /usr/local/src/bugfix.master/library/Icinga/Application/Modules/Module.php:435
|
||||||
msgid "This module has no description"
|
msgid "This module has no description"
|
||||||
msgstr "Dieses Modul hat keine Beschreibung"
|
msgstr "Dieses Modul hat keine Beschreibung"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Preference/GeneralForm.php:100
|
#: /usr/local/src/bugfix.master/application/views/scripts/config/devtools.phtml:5
|
||||||
|
msgid "UI Debug"
|
||||||
|
msgstr "UI Debug"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Preference/GeneralForm.php:43
|
||||||
msgid "Use Default Language"
|
msgid "Use Default Language"
|
||||||
msgstr "Standardsprache verwenden"
|
msgstr "Standardsprache verwenden"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Preference/GeneralForm.php:109
|
#: /usr/local/src/bugfix.master/application/forms/Preference/GeneralForm.php:52
|
||||||
msgid "Use the following language to display texts and messages"
|
msgid "Use the following language to display texts and messages"
|
||||||
msgstr ""
|
msgstr "Die folgende Sprache benutzen, um Texte und Nachrichten anzuzeigen"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Authentication/LoginForm.php:57
|
#: /usr/local/src/bugfix.master/application/forms/Authentication/LoginForm.php:24
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:194
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:169
|
||||||
msgid "Username"
|
msgid "Username"
|
||||||
msgstr "Benutzername"
|
msgstr "Benutzername"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:169
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/LdapBackendForm.php:144
|
||||||
msgid "Using ldap is not possible, the php extension \"ldap\" is not installed."
|
msgid "Using ldap is not possible, the php extension \"ldap\" is not installed."
|
||||||
msgstr ""
|
msgstr "Es ist nicht möglich, LDAP zu benutzen, da die PHP-Erweiterung \"LDAP\" nicht installiert ist."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:148
|
#: /usr/local/src/bugfix.master/application/forms/Config/Authentication/DbBackendForm.php:123
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Using the specified backend failed: %s"
|
msgid "Using the specified backend failed: %s"
|
||||||
msgstr ""
|
msgstr "Die angegebene Datenbank zu benutzen war nicht möglich: %s"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:87
|
#: /usr/local/src/bugfix.master/application/forms/Config/LoggingForm.php:61
|
||||||
msgid "Warning"
|
msgid "Warning"
|
||||||
msgstr "Warnung"
|
msgstr "Warnung"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:435
|
#: /usr/local/src/bugfix.master/application/views/scripts/dashboard/index.phtml:13
|
||||||
|
msgid "We tried to load a dashboard configuration with no success. Please have look that the configuration does exist:"
|
||||||
|
msgstr "Der Versuch die Dashboard-Konfiguration zu laden war nicht erfolgreich. Bitte stelle sicher, dass die folgende Konfigurationsdatei existiert:"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:410
|
||||||
msgid "You need to install the php extension \"mysql\" and the Zend_Pdo_Mysql classes to use MySQL database resources."
|
msgid "You need to install the php extension \"mysql\" and the Zend_Pdo_Mysql classes to use MySQL database resources."
|
||||||
msgstr ""
|
msgstr "Um MySQL Datenbank-Ressourcen nutzen zu können müssen die PHP-Erweiterung \"mysql\" sowie die Zend_Pdo_Mysql Klassen installiert sein."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:442
|
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:417
|
||||||
msgid "You need to install the php extension \"pgsql\" and the Zend_Pdo_Pgsql classes to use PostgreSQL database resources."
|
msgid "You need to install the php extension \"pgsql\" and the Zend_Pdo_Pgsql classes to use PostgreSQL database resources."
|
||||||
msgstr ""
|
msgstr "Um PostgreSQL Datenbank-Ressourcen nutzen zu können müssen die PHP-Erweiterung \"pqsql\" sowie die Zend_Pdo_Pgsql Klassen installiert sein."
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/application/forms/Preference/GeneralForm.php:106
|
#: /usr/local/src/bugfix.master/application/forms/Preference/GeneralForm.php:49
|
||||||
msgid "Your Current Language"
|
msgid "Your Current Language"
|
||||||
msgstr "Deine aktuelle Sprache"
|
msgstr "Deine aktuelle Sprache"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:108
|
#: /usr/local/src/bugfix.master/library/Icinga/Web/Widget/Limiter.php:58
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:114
|
msgid "all"
|
||||||
|
msgstr "alle"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:83
|
||||||
|
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:89
|
||||||
msgid "for"
|
msgid "for"
|
||||||
msgstr "für"
|
msgstr "für"
|
||||||
|
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:112
|
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:87
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:131
|
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:106
|
||||||
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:133
|
#: /usr/local/src/bugfix.master/library/Icinga/Util/Format.php:108
|
||||||
msgid "since"
|
msgid "since"
|
||||||
msgstr "seit"
|
msgstr "seit"
|
||||||
|
|
||||||
|
#: /usr/local/src/bugfix.master/application/views/scripts/config/devtools.phtml:5
|
||||||
|
msgid "toggle"
|
||||||
|
msgstr "umschalten"
|
||||||
|
|
||||||
|
#~ msgid "%d to %d of %d"
|
||||||
|
#~ msgstr "%d bis %d von %d"
|
||||||
|
|
||||||
|
#~ msgid "Installation"
|
||||||
|
#~ msgstr "Installation"
|
||||||
|
|
||||||
|
#~ msgid "Logging"
|
||||||
|
#~ msgstr "Logging"
|
||||||
|
|
||||||
|
#~ msgid "Previous"
|
||||||
|
#~ msgstr "Vorheriges"
|
||||||
|
|
||||||
#~ msgid "Icinga Users Login"
|
#~ msgid "Icinga Users Login"
|
||||||
#~ msgstr "Icinga Benutzeranmeldung"
|
#~ msgstr "Icinga Benutzeranmeldung"
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Application\Config;
|
|
||||||
use Icinga\Util\DateTimeFactory;
|
use Icinga\Util\DateTimeFactory;
|
||||||
use Icinga\Web\Form\Validator\DateTimeValidator;
|
use Icinga\Web\Form\Validator\DateTimeValidator;
|
||||||
|
|
||||||
@ -109,10 +108,8 @@ class Zend_View_Helper_DateFormat extends Zend_View_Helper_Abstract
|
|||||||
*/
|
*/
|
||||||
public function getDateFormat()
|
public function getDateFormat()
|
||||||
{
|
{
|
||||||
return $this->request->getUser()->getPreferences()->get(
|
// TODO(mh): Missing localized format (#6077)
|
||||||
'app.dateFormat',
|
return 'd/m/Y';
|
||||||
Config::app()->global !== null ? Config::app()->global->get('dateFormat', 'd/m/Y') : 'd/m/Y'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,10 +119,8 @@ class Zend_View_Helper_DateFormat extends Zend_View_Helper_Abstract
|
|||||||
*/
|
*/
|
||||||
public function getTimeFormat()
|
public function getTimeFormat()
|
||||||
{
|
{
|
||||||
return $this->request->getUser()->getPreferences()->get(
|
// TODO(mh): Missing localized format (#6077)
|
||||||
'app.timeFormat',
|
return 'g:i A';
|
||||||
Config::app()->global !== null ? Config::app()->global->get('timeFormat', 'g:i A') : 'g:i A'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
<?= $this->tabs ?>
|
<?= $this->tabs ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content" >
|
<div class="content">
|
||||||
<?= $this->form ?>
|
<h1><?= $this->escape($this->translate('This feature is deactivated at the moment.')); ?></h1>
|
||||||
|
<p>
|
||||||
|
<?=
|
||||||
|
$this->escape($this->translate('Please have a little patience, we are hard working on it, take a look at icingaweb2 issues.'));
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
@ -7,16 +7,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1>No dashboard configuration found!</h1>
|
<h1><?= $this->escape($this->translate('Welcome to Icinga Web!')) ?></h1>
|
||||||
<p>
|
<p><?= sprintf(
|
||||||
<?=
|
$this->escape($this->translate('Currently there is no dashlet available. This might change once you enabled some of the available %s.')),
|
||||||
$this->translate('We tried to load a dashboard configuration with no success.'
|
$this->qlink($this->translate('modules'), 'config/modules')
|
||||||
. ' Please have look that the configuration does exist:');
|
) ?></p>
|
||||||
?>
|
|
||||||
|
|
||||||
<code>
|
|
||||||
<?= $this->escape($this->configPath) ?>.ini
|
|
||||||
</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif ?>
|
@ -1 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
use Icinga\Web\Widget\SearchDashboard;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<? if (SearchDashboard::search('dummy')->getPane('search')->hasComponents()): ?>
|
||||||
|
<form action="<?= $this->href('search') ?>" method="get" role="search">
|
||||||
|
<input
|
||||||
|
type="text" name="q" class="search autofocus" placeholder="<?= $this->translate('Search...') ?>"
|
||||||
|
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
<? endif; ?>
|
||||||
<?= $menuRenderer; ?>
|
<?= $menuRenderer; ?>
|
@ -5,6 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
<?php if ($this->logData !== null): ?>
|
||||||
<table class="action">
|
<table class="action">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($this->logData as $value): ?>
|
<?php foreach ($this->logData as $value): ?>
|
||||||
@ -21,4 +22,5 @@
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
@ -1,12 +1,8 @@
|
|||||||
<div class="controls">
|
|
||||||
<?= $this->tabs ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1><?= $this->translate("I'm ready to search, waiting for your input") ?></h1>
|
<h1><?= $this->translate("I'm ready to search, waiting for your input") ?></h1>
|
||||||
<p><strong><?= $this->translate('Hint') ?>: </strong><?= $this->translate(
|
<p><strong><?= $this->translate('Hint') ?>: </strong><?= $this->translate(
|
||||||
'Please use the asterisk (*) as a placeholder for wildcard searches.'
|
'Please use the asterisk (*) as a placeholder for wildcard searches.'
|
||||||
. " For convenience I'll always add a wildcard after the last character"
|
. " For convenience I'll always add a wildcard in front and after your"
|
||||||
. ' you typed.'
|
. ' search string.'
|
||||||
) ?></p>
|
) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="controls">
|
<div class="controls">
|
||||||
<?= $this->tabs ?>
|
<?= $this->dashboard->getTabs() ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content dashboard">
|
<div class="content dashboard">
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
[global]
|
[global]
|
||||||
timezone = "Europe/Berlin"
|
timezone = "Europe/Berlin"
|
||||||
dateFormat = "d/m/Y"
|
|
||||||
timeFormat = "g:i A"
|
|
||||||
|
|
||||||
; Contains the directories that will be searched for available modules. Modules that
|
; Contains the directories that will be searched for available modules. Modules that
|
||||||
; don't exist in these directories can still be symlinked in the module folder, but
|
; don't exist in these directories can still be symlinked in the module folder, but
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
[Incidents]
|
|
||||||
title = "Current incidents"
|
|
||||||
|
|
||||||
[Incidents.Service Problems]
|
|
||||||
url = "monitoring/list/services"
|
|
||||||
service_problem = 1
|
|
||||||
limit = 10
|
|
||||||
sort = service_severity
|
|
||||||
|
|
||||||
[Incidents.Recently Recovered Services]
|
|
||||||
url = "monitoring/list/services"
|
|
||||||
sort = "service_last_state_change"
|
|
||||||
service_state = 0
|
|
||||||
limit = 10
|
|
||||||
dir = "desc"
|
|
||||||
|
|
||||||
[Incidents.Host Problems]
|
|
||||||
url = "monitoring/list/hosts"
|
|
||||||
host_problem = 1
|
|
||||||
sort = host_severity
|
|
||||||
|
|
||||||
[Landing]
|
|
||||||
title = "Landing page"
|
|
||||||
|
|
||||||
[Landing.Hostgroups]
|
|
||||||
url = "monitoring/chart/hostgroup"
|
|
||||||
|
|
||||||
[Landing.Servicegroups]
|
|
||||||
url = "monitoring/chart/servicegroup"
|
|
||||||
|
|
||||||
[Landing.Unhandled Problem Services]
|
|
||||||
url = "monitoring/list/services"
|
|
||||||
service_handled = 0
|
|
||||||
service_problem = 1
|
|
||||||
|
|
||||||
[Landing.Unhandled Problem Hosts]
|
|
||||||
url = "monitoring/list/hosts"
|
|
||||||
host_handled = 0
|
|
||||||
host_problem = 1
|
|
@ -1,34 +0,0 @@
|
|||||||
[Dashboard]
|
|
||||||
title = "Dashboard"
|
|
||||||
url = "dashboard"
|
|
||||||
icon = "img/icons/dashboard.png"
|
|
||||||
priority = 10
|
|
||||||
|
|
||||||
[System]
|
|
||||||
icon = img/icons/configuration.png
|
|
||||||
priority = 200
|
|
||||||
|
|
||||||
[System.Preferences]
|
|
||||||
title = "Preferences"
|
|
||||||
url = "preference"
|
|
||||||
priority = 200
|
|
||||||
|
|
||||||
[System.Configuration]
|
|
||||||
title = "Configuration"
|
|
||||||
url = "config"
|
|
||||||
priority = 300
|
|
||||||
|
|
||||||
[System.Modules]
|
|
||||||
title = "Modules"
|
|
||||||
url = "config/modules"
|
|
||||||
priority = 400
|
|
||||||
|
|
||||||
[System.ApplicationLog]
|
|
||||||
title = "Application log"
|
|
||||||
url = "list/applicationlog"
|
|
||||||
priority = 500
|
|
||||||
|
|
||||||
[Logout]
|
|
||||||
url = "authentication/logout"
|
|
||||||
icon = img/icons/logout.png
|
|
||||||
priority = 300
|
|
@ -1,5 +0,0 @@
|
|||||||
[Documentation]
|
|
||||||
title = "Documentation"
|
|
||||||
icon = "img/icons/comment.png"
|
|
||||||
url = "doc"
|
|
||||||
priority = 80
|
|
@ -1,109 +0,0 @@
|
|||||||
|
|
||||||
[Problems]
|
|
||||||
priority = 20
|
|
||||||
icon = "img/icons/error.png"
|
|
||||||
|
|
||||||
[Problems.Unhandled Hosts]
|
|
||||||
priority = 40
|
|
||||||
url = "monitoring/list/hosts?host_problem=1&host_handled=0"
|
|
||||||
|
|
||||||
[Problems.Unhandled Services]
|
|
||||||
priority = 40
|
|
||||||
url = "monitoring/list/services?service_problem=1&service_handled=0&sort=service_severity"
|
|
||||||
|
|
||||||
[Problems.Host Problems]
|
|
||||||
priority = 50
|
|
||||||
url = "monitoring/list/hosts?host_problem=1&sort=host_severity"
|
|
||||||
|
|
||||||
[Problems.Service Problems]
|
|
||||||
priority = 50
|
|
||||||
url = "monitoring/list/services?service_problem=1&sort=service_severity&dir=desc"
|
|
||||||
|
|
||||||
[Problems.Current Downtimes]
|
|
||||||
url = "monitoring/list/downtimes?downtime_is_in_effect=1"
|
|
||||||
|
|
||||||
[Overview]
|
|
||||||
priority = 30
|
|
||||||
icon = "img/icons/hostgroup.png"
|
|
||||||
|
|
||||||
[Overview.Tactical Overview]
|
|
||||||
title = "Tactical Overview"
|
|
||||||
url = "monitoring/tactical"
|
|
||||||
priority = 40
|
|
||||||
|
|
||||||
[Overview.Hosts]
|
|
||||||
title = "Hosts"
|
|
||||||
url = "monitoring/list/hosts"
|
|
||||||
priority = 50
|
|
||||||
|
|
||||||
[Overview.Services]
|
|
||||||
title = "Services"
|
|
||||||
url = "monitoring/list/services"
|
|
||||||
priority = 50
|
|
||||||
|
|
||||||
[Overview.Servicematrix]
|
|
||||||
title = "Servicematrix"
|
|
||||||
url = "monitoring/list/servicematrix?service_problem=1"
|
|
||||||
priority = 51
|
|
||||||
|
|
||||||
[Overview.Servicegroups]
|
|
||||||
title = "Servicegroups"
|
|
||||||
url = "monitoring/list/servicegroups"
|
|
||||||
priority = 60
|
|
||||||
|
|
||||||
[Overview.Hostgroups]
|
|
||||||
title = "Hostgroups"
|
|
||||||
url = "monitoring/list/hostgroups"
|
|
||||||
priority = 60
|
|
||||||
|
|
||||||
[Overview.Contactgroups]
|
|
||||||
title = "Contactgroups"
|
|
||||||
url = "monitoring/list/contactgroups"
|
|
||||||
priority = 61
|
|
||||||
|
|
||||||
[Overview.Downtimes]
|
|
||||||
title = "Downtimes"
|
|
||||||
url = "monitoring/list/downtimes"
|
|
||||||
priority = 70
|
|
||||||
|
|
||||||
[Overview.Comments]
|
|
||||||
title = "Comments"
|
|
||||||
url = "monitoring/list/comments?comment_type=(comment|ack)"
|
|
||||||
priority = 70
|
|
||||||
|
|
||||||
[Overview.Contacts]
|
|
||||||
title = "Contacts"
|
|
||||||
url = "monitoring/list/contacts"
|
|
||||||
priority = 70
|
|
||||||
|
|
||||||
[History]
|
|
||||||
icon = "img/icons/history.png"
|
|
||||||
|
|
||||||
[History.Critical Events]
|
|
||||||
title = "Critical Events"
|
|
||||||
url = "monitoring/list/statehistorysummary"
|
|
||||||
priority = 50
|
|
||||||
|
|
||||||
[History.Notifications]
|
|
||||||
title = "Notifications"
|
|
||||||
url = "monitoring/list/notifications"
|
|
||||||
|
|
||||||
[History.Events]
|
|
||||||
title = "All Events"
|
|
||||||
url = "monitoring/list/eventhistory?timestamp>=-7%20days"
|
|
||||||
|
|
||||||
[History.Timeline]
|
|
||||||
title = "Timeline"
|
|
||||||
url = "monitoring/timeline"
|
|
||||||
|
|
||||||
[System.Process Info]
|
|
||||||
title = "Process Info"
|
|
||||||
url = "monitoring/process/info"
|
|
||||||
priority = 120
|
|
||||||
|
|
||||||
[System.Performance Info]
|
|
||||||
title = "Performance Info"
|
|
||||||
url = "monitoring/process/performance"
|
|
||||||
priority = 130
|
|
||||||
|
|
||||||
|
|
0
doc/api/.gitkeep
Normal file
0
doc/api/.gitkeep
Normal file
@ -1,130 +0,0 @@
|
|||||||
# Frontend components
|
|
||||||
|
|
||||||
Frontend components are JavaScript modules that can be required directly through the HTML markup of
|
|
||||||
your view, to provide additional functionality for the user. Although its best practice to
|
|
||||||
make all features available without JavaScript, these components can be used to provide a richer
|
|
||||||
and more comfortable user experience in case JavaScript is available.
|
|
||||||
|
|
||||||
There is a certain set of frontend components which come directly with the Icinga2-Web core application,
|
|
||||||
but it is also possible to define new components directly in Icinga2-Web modules.
|
|
||||||
|
|
||||||
|
|
||||||
## How do components work?
|
|
||||||
|
|
||||||
Components are defined in JavaScript files that provide a set of functionality that will be added to the
|
|
||||||
targeted HTML node. Icinga2-Web uses [RequireJS](http://requirejs.org) to load
|
|
||||||
all frontend components, so each frontend component is in fact
|
|
||||||
[defined exactly like a RequireJS-Module](http://requirejs.org/docs/api.html#define) .
|
|
||||||
|
|
||||||
The important difference to plain RequireJS is, that the loading and execution of these components is
|
|
||||||
done automatically through the HTML markup. The attribute *data-icinga-component* in a DIV
|
|
||||||
element will indicate that this element is a container for a frontend component and will trigger
|
|
||||||
the component loader to create a component instance for this HTML node. The component loader
|
|
||||||
keeps track of all available components and makes it possible to retrieve this instance when needed.
|
|
||||||
|
|
||||||
|
|
||||||
### Component names
|
|
||||||
|
|
||||||
A component name consists of two parts: the namespace and the name of the component itself. The component
|
|
||||||
is named exactly like its JavaScript file, while the namespace is the name of the Icinga2-Web module that contains
|
|
||||||
the component. Each Icinga2-Web module can contain its own components in the folder *public/js*.
|
|
||||||
|
|
||||||
<module>/<component>
|
|
||||||
|
|
||||||
|
|
||||||
NOTE: The namespace used for modules defined in the Icinga2-Web core application is "app". In opposition to
|
|
||||||
the modules the core application keeps its modules located in *public/js/icinga/components*
|
|
||||||
instead of *public/js*.
|
|
||||||
|
|
||||||
|
|
||||||
#### Example Names
|
|
||||||
|
|
||||||
|
|
||||||
The full name for the component *modules/monitoring/public/js/someComponent.js* in the module "monitoring" would be:
|
|
||||||
|
|
||||||
"monitoring/someComponent"
|
|
||||||
|
|
||||||
|
|
||||||
The full component name for the component *public/js/icinga/components/datetime.js* in the Icinga2-Web core application
|
|
||||||
would:
|
|
||||||
|
|
||||||
"app/datetime"
|
|
||||||
|
|
||||||
|
|
||||||
## Creating a component
|
|
||||||
|
|
||||||
As described in the chapters above, components are defined exactly like RequireJS modules, but
|
|
||||||
with the additional requirement that they must always return a class constructor. The component below will
|
|
||||||
search all date pickers, set the time format and create a JavaScript date picker when there is no native one
|
|
||||||
available.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that our date/time controls will work on every browser (natively or javascript based)
|
|
||||||
*/
|
|
||||||
define(['jquery', 'datetimepicker'], function($) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var DateTimePicker = function(target) {
|
|
||||||
$(target).find('.datetime input')
|
|
||||||
.attr('data-format', 'yyyy-MM-dd hh:mm:ss');
|
|
||||||
|
|
||||||
$(target).find('.datetime')
|
|
||||||
.addClass('input-append')
|
|
||||||
.append('<span class="add-on">' +
|
|
||||||
'<i data-time-icon="icon-time" data-date-icon="icon-calendar"></i></span>')
|
|
||||||
.datetimepicker();
|
|
||||||
};
|
|
||||||
return DateTimePicker;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
## Loading a component
|
|
||||||
|
|
||||||
The following code will load the module *datetime*, which will ensure that there is always a datetime-picker
|
|
||||||
with right time-format available.
|
|
||||||
|
|
||||||
<div id="date-time-picker" data-icinga-component="app/datetime">
|
|
||||||
|
|
||||||
<div class="datetime">
|
|
||||||
<input data-format="dd/MM/yyyy hh:mm:ss" type="text"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
### Component ids
|
|
||||||
|
|
||||||
When an ID is assigned to the HTML element, it will be used by the component loader to reference this
|
|
||||||
component. Otherwise an ID in the form "icinga-component-<ID>" will be created and the ID attribute in the
|
|
||||||
HTML Element will be updated accordingly.
|
|
||||||
|
|
||||||
|
|
||||||
### Component "target"
|
|
||||||
|
|
||||||
The div-element with the *data-icinga-component* will be used as the "target" for the loaded component,
|
|
||||||
which means that the component will perform its actions on this HTML node.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Retrieving a component
|
|
||||||
|
|
||||||
Sometimes it can be necessary to retrieve the instances of the components itself, for example when they implement
|
|
||||||
additional functions that can be called. The component loader is available in the Icinga object and can be used
|
|
||||||
to retrieve component instances using their ID or their full component name.
|
|
||||||
|
|
||||||
|
|
||||||
## By component id
|
|
||||||
|
|
||||||
var component = Icinga.components.getById("component-id");
|
|
||||||
component.doSomething();
|
|
||||||
|
|
||||||
|
|
||||||
## By full component name
|
|
||||||
|
|
||||||
var components = Icinga.components.getByType("app/datetime");
|
|
||||||
// ... do something with every component of the type app/datetime
|
|
||||||
|
|
||||||
## All components
|
|
||||||
|
|
||||||
var components = Icinga.components.getComponents();
|
|
||||||
// ... do something with every component
|
|
@ -14,30 +14,4 @@ the objects you're interested in and can add and remove elements.
|
|||||||
* The dashboard itself is just the view containing the panes
|
* The dashboard itself is just the view containing the panes
|
||||||
|
|
||||||
|
|
||||||
## Configuration files
|
|
||||||
|
|
||||||
By default, the config/dashboard/dashboard.ini is used for storing dashboards in the following format:
|
|
||||||
|
|
||||||
[PaneName] ; Define a new Pane
|
|
||||||
title = "PaneTitle" ; The title of the pane as displayed in the tabls
|
|
||||||
|
|
||||||
[PaneName.Component1] ; Define a new component 'Component 1' underneat the pane
|
|
||||||
url = "/url/for/component1" ; the url that will be displayed, with view=compact as URL parameter appended
|
|
||||||
height = "500px" ; optional height setting
|
|
||||||
width = "400px" ; optional width setting
|
|
||||||
|
|
||||||
[test.My hosts] ; Another component, here with host
|
|
||||||
url = "monitoring/list/hosts" ; the url of the component
|
|
||||||
; Notice the missing height/width definition
|
|
||||||
|
|
||||||
[test.My services] ; And another pane
|
|
||||||
url = "monitoring/list/services" ; With service url
|
|
||||||
|
|
||||||
[test2] ; Define a second pane
|
|
||||||
title = "test2" ; with the title
|
|
||||||
|
|
||||||
[test2.test] ; Add a component to the second pane
|
|
||||||
url = "/monitoring/show/host/host1" ; ...and define it's url
|
|
||||||
|
|
||||||
|
|
||||||
[dashboards1]: res/Dashboard.png
|
[dashboards1]: res/Dashboard.png
|
||||||
|
@ -238,6 +238,77 @@ the labels to show you can use the 'disableLegend()' call on the GridChart objec
|
|||||||
|
|
||||||
![Various Line Graph Options][graph7]
|
![Various Line Graph Options][graph7]
|
||||||
|
|
||||||
|
|
||||||
|
### Tooltips
|
||||||
|
|
||||||
|
It is possible to specify custom tooltip format strings when creating bar charts.
|
||||||
|
Tooltips provide information about the points of each bar chart column, by aggregating
|
||||||
|
the values of all data sets with the same x-coordinate.
|
||||||
|
|
||||||
|
When no custom format string is given, a sane default format string is used, but its usually
|
||||||
|
clearer for the user to describe the data of each chart more accurately with a custom one.
|
||||||
|
|
||||||
|
|
||||||
|
**Example #9.1: Bar Charts with custom tooltips**
|
||||||
|
|
||||||
|
$this->chart->drawBars(
|
||||||
|
array(
|
||||||
|
'label' => 'Hosts critical',
|
||||||
|
'palette' => Palette::PROBLEM,
|
||||||
|
'stack' => 'stack1',
|
||||||
|
'data' => $data2,
|
||||||
|
'tooltip' => '{title}<br/> {value} of {sum} hosts are ok.'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'label' => 'Hosts warning',
|
||||||
|
'stack' => 'stack1',
|
||||||
|
'palette' => Palette::WARNING,
|
||||||
|
'data' => $data,
|
||||||
|
'tooltip' => '{title}<br/> Oh no, {value} of {sum} hosts are down!'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
As you can see, you can specify a format string for each data set, which allows you to
|
||||||
|
pass a custom message for all "down" hosts, one custom message for all "Ok" hosts and so on.
|
||||||
|
In contrast to that, the aggregation of values works on a column basis and will give you the
|
||||||
|
sum of all y-values with the same x-coordinate and not the aggregation of all values of the data set.
|
||||||
|
|
||||||
|
#### Rich Tooltips
|
||||||
|
|
||||||
|
It is also possible to use HTML in the tooltip strings to create rich tooltip markups, which can
|
||||||
|
be useful to provide extended output that spans over multiple lines. Please keep in mind that
|
||||||
|
users without JavaScript will see the tooltip with all of its html-tags stripped.
|
||||||
|
|
||||||
|
![Various Line Graph Options][graph7.1]
|
||||||
|
|
||||||
|
#### Available replacements
|
||||||
|
|
||||||
|
The available replacements depend on the used chart type, since the tooltip data is
|
||||||
|
instantiated and populated by the chart. All bar graphs have the following replacements available:
|
||||||
|
|
||||||
|
Aggregated values, are calculated from the data points of each column:
|
||||||
|
|
||||||
|
- sum: The amount of all Y-values of the current column
|
||||||
|
- max: The biggest occurring Y-value of the current column
|
||||||
|
- min: The smallest occurring Y-value of the current column
|
||||||
|
|
||||||
|
|
||||||
|
Column values are also defined by the current column, but are not
|
||||||
|
the product of any aggregation
|
||||||
|
|
||||||
|
- title: The x-value of the current column
|
||||||
|
|
||||||
|
|
||||||
|
Row values are defined by the properties the current data set, and are only useful for rendering the
|
||||||
|
generic tooltip correctly, since you could also just directly write
|
||||||
|
those values into your custom tooltip.
|
||||||
|
|
||||||
|
- label: The name of the current data set
|
||||||
|
- color: The color of this data set
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Pie Charts
|
## Pie Charts
|
||||||
|
|
||||||
### The PieChart Object
|
### The PieChart Object
|
||||||
@ -317,5 +388,6 @@ Rendering is straightforward, assuming $svg is the PieChart/GridChart object, yo
|
|||||||
[graph5]: res/GraphExample#5.png
|
[graph5]: res/GraphExample#5.png
|
||||||
[graph6]: res/GraphExample#6.png
|
[graph6]: res/GraphExample#6.png
|
||||||
[graph7]: res/GraphExample#7.png
|
[graph7]: res/GraphExample#7.png
|
||||||
|
[graph7.1]: res/GraphExample#7.1.png
|
||||||
[graph8]: res/GraphExample#8.png
|
[graph8]: res/GraphExample#8.png
|
||||||
[graph9]: res/GraphExample#9.png
|
[graph9]: res/GraphExample#9.png
|
BIN
doc/res/GraphExample#7.1.png
Normal file
BIN
doc/res/GraphExample#7.1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
@ -83,7 +83,7 @@ BuildArch: noarch
|
|||||||
AutoReqProv: Off
|
AutoReqProv: Off
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
Source0: icingaweb2-%{version}.tar.gz
|
Source: icingaweb2-%{version}.tar.gz
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||||
|
|
||||||
@ -181,15 +181,10 @@ install -D -m0644 packages/rpm/etc/httpd/conf.d/icingaweb.conf %{buildroot}/%{ap
|
|||||||
%{__cp} -r application library modules public %{buildroot}/%{sharedir}/
|
%{__cp} -r application library modules public %{buildroot}/%{sharedir}/
|
||||||
|
|
||||||
## config
|
## config
|
||||||
# use the default menu.ini for application and monitoring mobule
|
|
||||||
install -D -m0644 config/menu.ini %{buildroot}/%{_sysconfdir}/icingaweb/menu.ini
|
|
||||||
install -D -m0644 config/modules/monitoring/menu.ini %{buildroot}/%{_sysconfdir}/icingaweb/modules/monitoring/menu.ini
|
|
||||||
# authentication is db only
|
# authentication is db only
|
||||||
install -D -m0644 packages/rpm/etc/icingaweb/authentication.ini %{buildroot}/%{_sysconfdir}/icingaweb/authentication.ini
|
install -D -m0644 packages/rpm/etc/icingaweb/authentication.ini %{buildroot}/%{_sysconfdir}/icingaweb/authentication.ini
|
||||||
# custom resource paths
|
# custom resource paths
|
||||||
install -D -m0644 packages/rpm/etc/icingaweb/resources.ini %{buildroot}/%{_sysconfdir}/icingaweb/resources.ini
|
install -D -m0644 packages/rpm/etc/icingaweb/resources.ini %{buildroot}/%{_sysconfdir}/icingaweb/resources.ini
|
||||||
# dashboard
|
|
||||||
install -D -m0644 config/dashboard/dashboard.ini %{buildroot}/%{_sysconfdir}/icingaweb/dashboard/dashboard.ini
|
|
||||||
# monitoring module (icinga2)
|
# monitoring module (icinga2)
|
||||||
install -D -m0644 packages/rpm/etc/icingaweb/modules/monitoring/backends.ini %{buildroot}/%{_sysconfdir}/icingaweb/modules/monitoring/backends.ini
|
install -D -m0644 packages/rpm/etc/icingaweb/modules/monitoring/backends.ini %{buildroot}/%{_sysconfdir}/icingaweb/modules/monitoring/backends.ini
|
||||||
install -D -m0644 packages/rpm/etc/icingaweb/modules/monitoring/instances.ini %{buildroot}/%{_sysconfdir}/icingaweb/modules/monitoring/instances.ini
|
install -D -m0644 packages/rpm/etc/icingaweb/modules/monitoring/instances.ini %{buildroot}/%{_sysconfdir}/icingaweb/modules/monitoring/instances.ini
|
||||||
|
@ -14,6 +14,7 @@ use Icinga\Exception\NotReadableError;
|
|||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
use Icinga\Util\DateTimeFactory;
|
use Icinga\Util\DateTimeFactory;
|
||||||
use Icinga\Util\Translator;
|
use Icinga\Util\Translator;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class bootstraps a thin Icinga application layer
|
* This class bootstraps a thin Icinga application layer
|
||||||
@ -332,7 +333,7 @@ abstract class ApplicationBootstrap
|
|||||||
try {
|
try {
|
||||||
$this->moduleManager->loadEnabledModules();
|
$this->moduleManager->loadEnabledModules();
|
||||||
} catch (NotReadableError $e) {
|
} catch (NotReadableError $e) {
|
||||||
Logger::error(new Exception('Cannot load enabled modules. An exception was thrown:', 0, $e));
|
Logger::error(new IcingaException('Cannot load enabled modules. An exception was thrown:', $e));
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -369,7 +370,7 @@ abstract class ApplicationBootstrap
|
|||||||
try {
|
try {
|
||||||
$this->config = Config::app();
|
$this->config = Config::app();
|
||||||
} catch (NotReadableError $e) {
|
} catch (NotReadableError $e) {
|
||||||
Logger::error(new Exception('Cannot load application configuration. An exception was thrown:', 0, $e));
|
Logger::error(new IcingaException('Cannot load application configuration. An exception was thrown:', $e));
|
||||||
$this->config = new Zend_Config(array());
|
$this->config = new Zend_Config(array());
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
@ -417,7 +418,7 @@ abstract class ApplicationBootstrap
|
|||||||
ResourceFactory::setConfig($config);
|
ResourceFactory::setConfig($config);
|
||||||
} catch (NotReadableError $e) {
|
} catch (NotReadableError $e) {
|
||||||
Logger::error(
|
Logger::error(
|
||||||
new Exception('Cannot load resource configuration. An exception was thrown:', 0, $e)
|
new IcingaException('Cannot load resource configuration. An exception was thrown:', $e)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,9 +452,8 @@ abstract class ApplicationBootstrap
|
|||||||
*/
|
*/
|
||||||
protected function setupInternationalization()
|
protected function setupInternationalization()
|
||||||
{
|
{
|
||||||
$localeDir = $this->getApplicationDir('locale');
|
if ($this->hasLocales()) {
|
||||||
if (file_exists($localeDir) && is_dir($localeDir)) {
|
Translator::registerDomain(Translator::DEFAULT_DOMAIN, $this->getLocaleDir());
|
||||||
Translator::registerDomain(Translator::DEFAULT_DOMAIN, $localeDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -468,4 +468,48 @@ abstract class ApplicationBootstrap
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string Our locale directory
|
||||||
|
*/
|
||||||
|
public function getLocaleDir()
|
||||||
|
{
|
||||||
|
return $this->getApplicationDir('locale');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return bool Whether Icinga Web has translations
|
||||||
|
*/
|
||||||
|
public function hasLocales()
|
||||||
|
{
|
||||||
|
$localedir = $this->getLocaleDir();
|
||||||
|
return file_exists($localedir) && is_dir($localedir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all available locales
|
||||||
|
*
|
||||||
|
* NOTE: Might be a candidate for a static function in Translator
|
||||||
|
*
|
||||||
|
* return array Locale list
|
||||||
|
*/
|
||||||
|
public function listLocales()
|
||||||
|
{
|
||||||
|
$locales = array();
|
||||||
|
if (! $this->hasLocales()) {
|
||||||
|
return $locales;
|
||||||
|
}
|
||||||
|
$localedir = $this->getLocaleDir();
|
||||||
|
|
||||||
|
$dh = opendir($localedir);
|
||||||
|
while (false !== ($file = readdir($dh))) {
|
||||||
|
$filename = $localedir . DIRECTORY_SEPARATOR . $file;
|
||||||
|
if (preg_match('/^[a-z]{2}_[A-Z]{2}$/', $file) && is_dir($filename)) {
|
||||||
|
$locales[] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir($dh);
|
||||||
|
sort($locales);
|
||||||
|
return $locales;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,10 @@ class Config extends Zend_Config
|
|||||||
$this->configFile = $filepath;
|
$this->configFile = $filepath;
|
||||||
$this->merge(new Zend_Config_Ini($filepath));
|
$this->merge(new Zend_Config_Ini($filepath));
|
||||||
} else {
|
} else {
|
||||||
throw new NotReadableError('Cannot read config file "' . $filename . '". Permission denied');
|
throw new NotReadableError(
|
||||||
|
'Cannot read config file "%s". Permission denied',
|
||||||
|
$filename
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +85,18 @@ class Config extends Zend_Config
|
|||||||
return self::$app[$configname];
|
return self::$app[$configname];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set module config
|
||||||
|
*
|
||||||
|
* @param string $moduleName
|
||||||
|
* @param string $configName
|
||||||
|
* @param Zend_Config $config
|
||||||
|
*/
|
||||||
|
public static function setModuleConfig($moduleName, $configName, Zend_Config $config)
|
||||||
|
{
|
||||||
|
self::$modules[$moduleName][$configName] = $config;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a module config instance
|
* Retrieve a module config instance
|
||||||
*
|
*
|
||||||
|
@ -39,11 +39,11 @@ class Loader
|
|||||||
public function registerNamespace($namespace, $directory)
|
public function registerNamespace($namespace, $directory)
|
||||||
{
|
{
|
||||||
if (!is_dir($directory)) {
|
if (!is_dir($directory)) {
|
||||||
throw new ProgrammingError(sprintf(
|
throw new ProgrammingError(
|
||||||
'Directory "%s" for namespace "%s" does not exist',
|
'Directory "%s" for namespace "%s" does not exist',
|
||||||
$directory,
|
$directory,
|
||||||
$namespace
|
$namespace
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->namespaces[$namespace] = $directory;
|
$this->namespaces[$namespace] = $directory;
|
||||||
|
@ -110,12 +110,14 @@ class Manager
|
|||||||
}
|
}
|
||||||
if (!is_dir($this->enableDir)) {
|
if (!is_dir($this->enableDir)) {
|
||||||
throw new NotReadableError(
|
throw new NotReadableError(
|
||||||
'Cannot read enabled modules. Module directory "' . $this->enableDir . '" is not a directory'
|
'Cannot read enabled modules. Module directory "%s" is not a directory',
|
||||||
|
$this->enableDir
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!is_readable($this->enableDir)) {
|
if (!is_readable($this->enableDir)) {
|
||||||
throw new NotReadableError(
|
throw new NotReadableError(
|
||||||
'Cannot read enabled modules. Module directory "' . $this->enableDir . '" is not readable'
|
'Cannot read enabled modules. Module directory "%s" is not readable',
|
||||||
|
$this->enableDir
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (($dh = opendir($canonical)) !== false) {
|
if (($dh = opendir($canonical)) !== false) {
|
||||||
@ -206,10 +208,8 @@ class Manager
|
|||||||
{
|
{
|
||||||
if (!$this->hasInstalled($name)) {
|
if (!$this->hasInstalled($name)) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
sprintf(
|
|
||||||
'Cannot enable module "%s". Module is not installed.',
|
'Cannot enable module "%s". Module is not installed.',
|
||||||
$name
|
$name
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,8 +219,8 @@ class Manager
|
|||||||
|
|
||||||
if (!is_writable($this->enableDir)) {
|
if (!is_writable($this->enableDir)) {
|
||||||
throw new SystemPermissionException(
|
throw new SystemPermissionException(
|
||||||
'Can not enable module "' . $name . '". '
|
'Can not enable module "%s". Insufficient system permissions for enabling modules.',
|
||||||
. 'Insufficient system permissions for enabling modules.'
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,9 +232,11 @@ class Manager
|
|||||||
$error = error_get_last();
|
$error = error_get_last();
|
||||||
if (strstr($error["message"], "File exists") === false) {
|
if (strstr($error["message"], "File exists") === false) {
|
||||||
throw new SystemPermissionException(
|
throw new SystemPermissionException(
|
||||||
'Could not enable module "' . $name . '" due to file system errors. '
|
'Could not enable module "%s" due to file system errors. '
|
||||||
. 'Please check path and mounting points because this is not a permission error. '
|
. 'Please check path and mounting points because this is not a permission error. '
|
||||||
. 'Primary error was: ' . $error['message']
|
. 'Primary error was: %s',
|
||||||
|
$name,
|
||||||
|
$error['message']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,14 +270,18 @@ class Manager
|
|||||||
}
|
}
|
||||||
$link = $this->enableDir . '/' . $name;
|
$link = $this->enableDir . '/' . $name;
|
||||||
if (!file_exists($link)) {
|
if (!file_exists($link)) {
|
||||||
throw new ConfigurationError('Could not disable module. The module ' . $name . ' was not found.');
|
throw new ConfigurationError(
|
||||||
|
'Could not disable module. The module %s was not found.',
|
||||||
|
$name
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!is_link($link)) {
|
if (!is_link($link)) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Could not disable module. The module "' . $name . '" is not a symlink. '
|
'Could not disable module. The module "%s" is not a symlink. '
|
||||||
. 'It looks like you have installed this module manually and moved it to your module folder. '
|
. 'It looks like you have installed this module manually and moved it to your module folder. '
|
||||||
. 'In order to dynamically enable and disable modules, you have to create a symlink to '
|
. 'In order to dynamically enable and disable modules, you have to create a symlink to '
|
||||||
. 'the enabled_modules folder.'
|
. 'the enabled_modules folder.',
|
||||||
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,9 +289,11 @@ class Manager
|
|||||||
if (!@unlink($link)) {
|
if (!@unlink($link)) {
|
||||||
$error = error_get_last();
|
$error = error_get_last();
|
||||||
throw new SystemPermissionException(
|
throw new SystemPermissionException(
|
||||||
'Could not disable module "' . $name . '" due to file system errors. '
|
'Could not disable module "%s" due to file system errors. '
|
||||||
. 'Please check path and mounting points because this is not a permission error. '
|
. 'Please check path and mounting points because this is not a permission error. '
|
||||||
. 'Primary error was: ' . $error['message']
|
. 'Primary error was: %s',
|
||||||
|
$name,
|
||||||
|
$error['message']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,10 +327,8 @@ class Manager
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw new ProgrammingError(
|
throw new ProgrammingError(
|
||||||
sprintf(
|
|
||||||
'Trying to access uninstalled module dir: %s',
|
'Trying to access uninstalled module dir: %s',
|
||||||
$name
|
$name
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,10 +394,8 @@ class Manager
|
|||||||
{
|
{
|
||||||
if (!$this->hasLoaded($name)) {
|
if (!$this->hasLoaded($name)) {
|
||||||
throw new ProgrammingError(
|
throw new ProgrammingError(
|
||||||
sprintf(
|
|
||||||
'Cannot access module %s as it hasn\'t been loaded',
|
'Cannot access module %s as it hasn\'t been loaded',
|
||||||
$name
|
$name
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $this->loadedModules[$name];
|
return $this->loadedModules[$name];
|
||||||
|
@ -5,17 +5,22 @@
|
|||||||
namespace Icinga\Application\Modules;
|
namespace Icinga\Application\Modules;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Zend_Config;
|
||||||
use Zend_Controller_Router_Route_Abstract;
|
use Zend_Controller_Router_Route_Abstract;
|
||||||
use Zend_Controller_Router_Route as Route;
|
use Zend_Controller_Router_Route as Route;
|
||||||
|
use Zend_Controller_Router_Route_Regex as RegexRoute;
|
||||||
use Icinga\Application\ApplicationBootstrap;
|
use Icinga\Application\ApplicationBootstrap;
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
use Icinga\Util\Translator;
|
use Icinga\Util\Translator;
|
||||||
use Icinga\Web\Hook;
|
use Icinga\Web\Hook;
|
||||||
|
use Icinga\Web\Menu;
|
||||||
use Icinga\Web\Widget;
|
use Icinga\Web\Widget;
|
||||||
|
use Icinga\Web\Widget\Dashboard\Pane;
|
||||||
use Icinga\Util\File;
|
use Icinga\Util\File;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\ProgrammingError;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module handling
|
* Module handling
|
||||||
@ -136,7 +141,6 @@ class Module
|
|||||||
*/
|
*/
|
||||||
private $app;
|
private $app;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Routes to add to the route chain
|
* Routes to add to the route chain
|
||||||
*
|
*
|
||||||
@ -146,6 +150,97 @@ class Module
|
|||||||
*/
|
*/
|
||||||
protected $routes = array();
|
protected $routes = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of menu elements
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $menuItems = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of Pane elements
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $paneItems = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $searchUrls = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $title
|
||||||
|
* @param string $url
|
||||||
|
*/
|
||||||
|
public function provideSearchUrl($title, $url)
|
||||||
|
{
|
||||||
|
$searchUrl = (object) array(
|
||||||
|
'title' => $title,
|
||||||
|
'url' => $url
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->searchUrls[] = $searchUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSearchUrls()
|
||||||
|
{
|
||||||
|
$this->launchConfigScript();
|
||||||
|
return $this->searchUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Menu Items
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getPaneItems()
|
||||||
|
{
|
||||||
|
$this->launchConfigScript();
|
||||||
|
return $this->paneItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a pane to dashboard
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
* @return Pane
|
||||||
|
*/
|
||||||
|
protected function dashboard($name)
|
||||||
|
{
|
||||||
|
$this->paneItems[$name] = new Pane($name);
|
||||||
|
return $this->paneItems[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Menu Items
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getMenuItems()
|
||||||
|
{
|
||||||
|
$this->launchConfigScript();
|
||||||
|
return $this->menuItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a menu Section to the Sidebar menu
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
* @param array $properties
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function menuSection($name, array $properties = array())
|
||||||
|
{
|
||||||
|
if (array_key_exists($name, $this->menuItems)) {
|
||||||
|
$this->menuItems[$name]->setProperties($properties);
|
||||||
|
} else {
|
||||||
|
$this->menuItems[$name] = new Menu($name, new Zend_Config($properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->menuItems[$name];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new module object
|
* Create a new module object
|
||||||
*
|
*
|
||||||
@ -559,8 +654,9 @@ class Module
|
|||||||
protected function providePermission($name, $description)
|
protected function providePermission($name, $description)
|
||||||
{
|
{
|
||||||
if ($this->providesPermission($name)) {
|
if ($this->providesPermission($name)) {
|
||||||
throw new Exception(
|
throw new IcingaException(
|
||||||
sprintf('Cannot provide permission "%s" twice', $name)
|
'Cannot provide permission "%s" twice',
|
||||||
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->permissionList[$name] = (object) array(
|
$this->permissionList[$name] = (object) array(
|
||||||
@ -580,8 +676,9 @@ class Module
|
|||||||
protected function provideRestriction($name, $description)
|
protected function provideRestriction($name, $description)
|
||||||
{
|
{
|
||||||
if ($this->providesRestriction($name)) {
|
if ($this->providesRestriction($name)) {
|
||||||
throw new Exception(
|
throw new IcingaException(
|
||||||
sprintf('Cannot provide restriction "%s" twice', $name)
|
'Cannot provide restriction "%s" twice',
|
||||||
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->restrictionList[$name] = (object) array(
|
$this->restrictionList[$name] = (object) array(
|
||||||
@ -637,12 +734,44 @@ class Module
|
|||||||
*/
|
*/
|
||||||
protected function registerLocales()
|
protected function registerLocales()
|
||||||
{
|
{
|
||||||
if (file_exists($this->localedir) && is_dir($this->localedir)) {
|
if ($this->hasLocales()) {
|
||||||
Translator::registerDomain($this->name, $this->localedir);
|
Translator::registerDomain($this->name, $this->localedir);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return bool Whether this module has translations
|
||||||
|
*/
|
||||||
|
public function hasLocales()
|
||||||
|
{
|
||||||
|
return file_exists($this->localedir) && is_dir($this->localedir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all available locales
|
||||||
|
*
|
||||||
|
* return array Locale list
|
||||||
|
*/
|
||||||
|
public function listLocales()
|
||||||
|
{
|
||||||
|
$locales = array();
|
||||||
|
if (! $this->hasLocales()) {
|
||||||
|
return $locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dh = opendir($this->localedir);
|
||||||
|
while (false !== ($file = readdir($dh))) {
|
||||||
|
$filename = $this->localedir . DIRECTORY_SEPARATOR . $file;
|
||||||
|
if (preg_match('/^[a-z]{2}_[A-Z]{2}$/', $file) && is_dir($filename)) {
|
||||||
|
$locales[] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir($dh);
|
||||||
|
sort($locales);
|
||||||
|
return $locales;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register web integration
|
* Register web integration
|
||||||
*
|
*
|
||||||
@ -693,12 +822,15 @@ class Module
|
|||||||
);
|
);
|
||||||
$router->addRoute(
|
$router->addRoute(
|
||||||
$this->name . '_img',
|
$this->name . '_img',
|
||||||
new Route(
|
new RegexRoute(
|
||||||
'img/' . $this->name . '/:file',
|
'img/' . $this->name . '/(.+)',
|
||||||
array(
|
array(
|
||||||
'controller' => 'static',
|
'controller' => 'static',
|
||||||
'action' => 'img',
|
'action' => 'img',
|
||||||
'module_name' => $this->name
|
'module_name' => $this->name
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
1 => 'file'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -781,4 +913,15 @@ class Module
|
|||||||
$this->routes[$name] = $route;
|
$this->routes[$name] = $route;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate a string with the global mt()
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
* @return mixed|string
|
||||||
|
*/
|
||||||
|
protected function translate($string)
|
||||||
|
{
|
||||||
|
return mt($this->name, $string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,57 @@
|
|||||||
|
|
||||||
namespace Icinga\Application;
|
namespace Icinga\Application;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Platform tests for icingaweb
|
||||||
|
*/
|
||||||
class Platform
|
class Platform
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Domain name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected static $domain;
|
protected static $domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected static $hostname;
|
protected static $hostname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fully qualified domain name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected static $fqdn;
|
protected static $fqdn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of windows
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public static function isWindows()
|
public static function isWindows()
|
||||||
{
|
{
|
||||||
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
|
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of linux
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public static function isLinux()
|
public static function isLinux()
|
||||||
{
|
{
|
||||||
return strtoupper(substr(PHP_OS, 0, 5)) === 'LINUX';
|
return strtoupper(substr(PHP_OS, 0, 5)) === 'LINUX';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of CLI environment
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public static function isCli()
|
public static function isCli()
|
||||||
{
|
{
|
||||||
if (PHP_SAPI == 'cli') {
|
if (PHP_SAPI == 'cli') {
|
||||||
@ -31,6 +66,11 @@ class Platform
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hostname
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public static function getHostname()
|
public static function getHostname()
|
||||||
{
|
{
|
||||||
if (self::$hostname === null) {
|
if (self::$hostname === null) {
|
||||||
@ -39,6 +79,11 @@ class Platform
|
|||||||
return self::$hostname;
|
return self::$hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the domain name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public static function getDomain()
|
public static function getDomain()
|
||||||
{
|
{
|
||||||
if (self::$domain === null) {
|
if (self::$domain === null) {
|
||||||
@ -47,6 +92,11 @@ class Platform
|
|||||||
return self::$domain;
|
return self::$domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the fully qualified domain name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public static function getFqdn()
|
public static function getFqdn()
|
||||||
{
|
{
|
||||||
if (self::$fqdn === null) {
|
if (self::$fqdn === null) {
|
||||||
@ -55,6 +105,9 @@ class Platform
|
|||||||
return self::$fqdn;
|
return self::$fqdn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize domain and host strings
|
||||||
|
*/
|
||||||
protected static function discoverHostname()
|
protected static function discoverHostname()
|
||||||
{
|
{
|
||||||
self::$hostname = gethostname();
|
self::$hostname = gethostname();
|
||||||
@ -66,4 +119,16 @@ class Platform
|
|||||||
self::$domain = array_shift(preg_split('~\.~', self::$hostname, 2));
|
self::$domain = array_shift(preg_split('~\.~', self::$hostname, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for php extension
|
||||||
|
*
|
||||||
|
* @param string $extensionName E.g. mysql, ldap
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function extensionLoaded($extensionName)
|
||||||
|
{
|
||||||
|
return extension_loaded($extensionName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,10 @@ use Icinga\Authentication\Manager as AuthenticationManager;
|
|||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
use Icinga\Exception\NotReadableError;
|
use Icinga\Exception\NotReadableError;
|
||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
|
use Icinga\Util\TimezoneDetect;
|
||||||
use Icinga\Web\Request;
|
use Icinga\Web\Request;
|
||||||
use Icinga\Web\Response;
|
use Icinga\Web\Response;
|
||||||
use Icinga\Web\View;
|
use Icinga\Web\View;
|
||||||
use Icinga\Web\Session\Session as BaseSession;
|
|
||||||
use Icinga\Web\Session;
|
|
||||||
use Icinga\User;
|
use Icinga\User;
|
||||||
use Icinga\Util\Translator;
|
use Icinga\Util\Translator;
|
||||||
use Icinga\Util\DateTimeFactory;
|
use Icinga\Util\DateTimeFactory;
|
||||||
@ -59,13 +58,6 @@ class Web extends ApplicationBootstrap
|
|||||||
*/
|
*/
|
||||||
private $request;
|
private $request;
|
||||||
|
|
||||||
/**
|
|
||||||
* Session object
|
|
||||||
*
|
|
||||||
* @var BaseSession
|
|
||||||
*/
|
|
||||||
private $session;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User object
|
* User object
|
||||||
*
|
*
|
||||||
@ -92,7 +84,6 @@ class Web extends ApplicationBootstrap
|
|||||||
->setupErrorHandling()
|
->setupErrorHandling()
|
||||||
->loadConfig()
|
->loadConfig()
|
||||||
->setupResourceFactory()
|
->setupResourceFactory()
|
||||||
->setupSession()
|
|
||||||
->setupUser()
|
->setupUser()
|
||||||
->setupTimezone()
|
->setupTimezone()
|
||||||
->setupLogger()
|
->setupLogger()
|
||||||
@ -172,7 +163,6 @@ class Web extends ApplicationBootstrap
|
|||||||
|
|
||||||
$this->setupFrontController();
|
$this->setupFrontController();
|
||||||
$this->setupViewRenderer();
|
$this->setupViewRenderer();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,17 +182,6 @@ class Web extends ApplicationBootstrap
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a session provider
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
private function setupSession()
|
|
||||||
{
|
|
||||||
$this->session = Session::create();
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject dependencies into request
|
* Inject dependencies into request
|
||||||
*
|
*
|
||||||
@ -295,10 +274,11 @@ class Web extends ApplicationBootstrap
|
|||||||
*/
|
*/
|
||||||
protected function setupTimezone()
|
protected function setupTimezone()
|
||||||
{
|
{
|
||||||
if ($this->user !== null && $this->user->getPreferences() !== null) {
|
|
||||||
$userTimezone = $this->user->getPreferences()->get('app.timezone');
|
|
||||||
} else {
|
|
||||||
$userTimezone = null;
|
$userTimezone = null;
|
||||||
|
|
||||||
|
if ($this->user !== null && $this->user->getPreferences() !== null) {
|
||||||
|
$detect = new TimezoneDetect();
|
||||||
|
$userTimezone = $this->user->getPreferences()->get('app.timezone', $detect->getTimezoneName());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
// {{{ICINGA_LICENSE_HEADER}}}
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
use \Icinga\Util\Translator;
|
use Icinga\Util\Translator;
|
||||||
|
|
||||||
if (extension_loaded('gettext')) {
|
if (extension_loaded('gettext')) {
|
||||||
function t($messageId)
|
function t($messageId)
|
||||||
|
@ -97,7 +97,9 @@ class AuthChain implements Iterator
|
|||||||
} catch (ConfigurationError $e) {
|
} catch (ConfigurationError $e) {
|
||||||
Logger::error(
|
Logger::error(
|
||||||
new ConfigurationError(
|
new ConfigurationError(
|
||||||
'Cannot create authentication backend "' . $name . '". An exception was thrown:', 0, $e
|
'Cannot create authentication backend "%s". An exception was thrown:',
|
||||||
|
$name,
|
||||||
|
$e
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->next();
|
$this->next();
|
||||||
|
@ -11,6 +11,7 @@ use Icinga\Exception\AuthenticationException;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Zend_Db_Expr;
|
use Zend_Db_Expr;
|
||||||
use Zend_Db_Select;
|
use Zend_Db_Select;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
class DbUserBackend extends UserBackend
|
class DbUserBackend extends UserBackend
|
||||||
{
|
{
|
||||||
@ -60,7 +61,10 @@ class DbUserBackend extends UserBackend
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($salt === '') {
|
if ($salt === '') {
|
||||||
throw new Exception('Cannot find salt for user ' . $user->getUsername());
|
throw new IcingaException(
|
||||||
|
'Cannot find salt for user %s',
|
||||||
|
$user->getUsername()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$select = new Zend_Db_Select($this->conn->getConnection());
|
$select = new Zend_Db_Select($this->conn->getConnection());
|
||||||
@ -73,12 +77,9 @@ class DbUserBackend extends UserBackend
|
|||||||
return ($row !== false) ? true : false;
|
return ($row !== false) ? true : false;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new AuthenticationException(
|
throw new AuthenticationException(
|
||||||
sprintf(
|
|
||||||
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
||||||
$user->getUsername(),
|
$user->getUsername(),
|
||||||
$this->getName()
|
$this->getName(),
|
||||||
),
|
|
||||||
0,
|
|
||||||
$e
|
$e
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -68,21 +68,17 @@ class LdapUserBackend extends UserBackend
|
|||||||
$result = $q->fetchRow();
|
$result = $q->fetchRow();
|
||||||
if (! isset($result)) {
|
if (! isset($result)) {
|
||||||
throw new AuthenticationException(
|
throw new AuthenticationException(
|
||||||
sprintf(
|
|
||||||
'No objects with objectClass="%s" in DN="%s" found.',
|
'No objects with objectClass="%s" in DN="%s" found.',
|
||||||
$this->userClass,
|
$this->userClass,
|
||||||
$this->conn->getDN()
|
$this->conn->getDN()
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! isset($result->{$this->userNameAttribute})) {
|
if (! isset($result->{$this->userNameAttribute})) {
|
||||||
throw new AuthenticationException(
|
throw new AuthenticationException(
|
||||||
sprintf(
|
|
||||||
'UserNameAttribute "%s" not existing in objectClass="%s"',
|
'UserNameAttribute "%s" not existing in objectClass="%s"',
|
||||||
$this->userNameAttribute,
|
$this->userNameAttribute,
|
||||||
$this->userClass
|
$this->userClass
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,11 +117,8 @@ class LdapUserBackend extends UserBackend
|
|||||||
} catch (AuthenticationException $e) {
|
} catch (AuthenticationException $e) {
|
||||||
// Authentication not possible
|
// Authentication not possible
|
||||||
throw new AuthenticationException(
|
throw new AuthenticationException(
|
||||||
sprintf(
|
|
||||||
'Authentication against backend "%s" not possible: ',
|
'Authentication against backend "%s" not possible: ',
|
||||||
$this->getName()
|
$this->getName(),
|
||||||
),
|
|
||||||
0,
|
|
||||||
$e
|
$e
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -141,12 +134,9 @@ class LdapUserBackend extends UserBackend
|
|||||||
} catch (LdapException $e) {
|
} catch (LdapException $e) {
|
||||||
// Error during authentication of this specific user
|
// Error during authentication of this specific user
|
||||||
throw new AuthenticationException(
|
throw new AuthenticationException(
|
||||||
sprintf(
|
|
||||||
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
||||||
$user->getUsername(),
|
$user->getUsername(),
|
||||||
$this->getName()
|
$this->getName(),
|
||||||
),
|
|
||||||
0,
|
|
||||||
$e
|
$e
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ use Icinga\Exception\NotReadableError;
|
|||||||
use Icinga\Application\Config as IcingaConfig;
|
use Icinga\Application\Config as IcingaConfig;
|
||||||
use Icinga\User\Preferences;
|
use Icinga\User\Preferences;
|
||||||
use Icinga\User\Preferences\PreferencesStore;
|
use Icinga\User\Preferences\PreferencesStore;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
class Manager
|
class Manager
|
||||||
{
|
{
|
||||||
@ -55,7 +56,11 @@ class Manager
|
|||||||
$config = IcingaConfig::app();
|
$config = IcingaConfig::app();
|
||||||
} catch (NotReadableError $e) {
|
} catch (NotReadableError $e) {
|
||||||
Logger::error(
|
Logger::error(
|
||||||
new Exception('Cannot load preferences for user "' . $username . '". An exception was thrown', 0, $e)
|
new IcingaException(
|
||||||
|
'Cannot load preferences for user "%s". An exception was thrown',
|
||||||
|
$username,
|
||||||
|
$e
|
||||||
|
)
|
||||||
);
|
);
|
||||||
$config = new Zend_Config(array());
|
$config = new Zend_Config(array());
|
||||||
}
|
}
|
||||||
@ -68,8 +73,10 @@ class Manager
|
|||||||
$preferences = new Preferences($preferencesStore->load());
|
$preferences = new Preferences($preferencesStore->load());
|
||||||
} catch (NotReadableError $e) {
|
} catch (NotReadableError $e) {
|
||||||
Logger::error(
|
Logger::error(
|
||||||
new Exception(
|
new IcingaException(
|
||||||
'Cannot load preferences for user "' . $username . '". An exception was thrown', 0, $e
|
'Cannot load preferences for user "%s". An exception was thrown',
|
||||||
|
$username,
|
||||||
|
$e
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$preferences = new Preferences();
|
$preferences = new Preferences();
|
||||||
|
@ -54,16 +54,18 @@ abstract class UserBackend implements Countable
|
|||||||
// Use a custom backend class, this is only useful for testing
|
// Use a custom backend class, this is only useful for testing
|
||||||
if (!class_exists($backendConfig->class)) {
|
if (!class_exists($backendConfig->class)) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Authentication configuration for backend "' . $name . '" defines an invalid backend'
|
'Authentication configuration for backend "%s" defines an invalid backend class.'
|
||||||
. ' class. Backend class "' . $backendConfig->class. '" not found'
|
. ' Backend class "%s" not found',
|
||||||
|
$name,
|
||||||
|
$backendConfig->class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return new $backendConfig->class($backendConfig);
|
return new $backendConfig->class($backendConfig);
|
||||||
}
|
}
|
||||||
if (($backendType = $backendConfig->backend) === null) {
|
if (($backendType = $backendConfig->backend) === null) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Authentication configuration for backend "' . $name
|
'Authentication configuration for backend "%s" is missing the backend directive',
|
||||||
. '" is missing the backend directive'
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$backendType = strtolower($backendType);
|
$backendType = strtolower($backendType);
|
||||||
@ -74,8 +76,8 @@ abstract class UserBackend implements Countable
|
|||||||
}
|
}
|
||||||
if ($backendConfig->resource === null) {
|
if ($backendConfig->resource === null) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Authentication configuration for backend "' . $name
|
'Authentication configuration for backend "%s" is missing the resource directive',
|
||||||
. '" is missing the resource directive'
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -100,22 +102,24 @@ abstract class UserBackend implements Countable
|
|||||||
case 'ldap':
|
case 'ldap':
|
||||||
if (($userClass = $backendConfig->user_class) === null) {
|
if (($userClass = $backendConfig->user_class) === null) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Authentication configuration for backend "' . $name
|
'Authentication configuration for backend "%s" is missing the user_class directive',
|
||||||
. '" is missing the user_class directive'
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (($userNameAttribute = $backendConfig->user_name_attribute) === null) {
|
if (($userNameAttribute = $backendConfig->user_name_attribute) === null) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Authentication configuration for backend "' . $name
|
'Authentication configuration for backend "%s" is missing the user_name_attribute directive',
|
||||||
. '" is missing the user_name_attribute directive'
|
$name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$backend = new LdapUserBackend($resource, $userClass, $userNameAttribute);
|
$backend = new LdapUserBackend($resource, $userClass, $userNameAttribute);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Authentication configuration for backend "' . $name. '" defines an invalid backend'
|
'Authentication configuration for backend "%s" defines an invalid backend type.'
|
||||||
. ' type. Backend type "' . $backendType . '" is not supported'
|
. ' Backend type "%s" is not supported',
|
||||||
|
$name,
|
||||||
|
$backendType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$backend->setName($name);
|
$backend->setName($name);
|
||||||
|
@ -9,12 +9,15 @@ use Icinga\Chart\Legend;
|
|||||||
use Icinga\Chart\Palette;
|
use Icinga\Chart\Palette;
|
||||||
use Icinga\Chart\Primitive\Drawable;
|
use Icinga\Chart\Primitive\Drawable;
|
||||||
use Icinga\Chart\SVGRenderer;
|
use Icinga\Chart\SVGRenderer;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for charts, extended by all other Chart classes.
|
* Base class for charts, extended by all other Chart classes.
|
||||||
*/
|
*/
|
||||||
abstract class Chart implements Drawable
|
abstract class Chart implements Drawable
|
||||||
{
|
{
|
||||||
|
protected $align = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SVG renderer that handles
|
* SVG renderer that handles
|
||||||
*
|
*
|
||||||
@ -89,17 +92,31 @@ abstract class Chart implements Drawable
|
|||||||
*
|
*
|
||||||
* @return string The SVG created by the SvgRenderer
|
* @return string The SVG created by the SvgRenderer
|
||||||
*
|
*
|
||||||
* @throws Exception Thrown wen the dataset is not valid for this graph
|
* @throws IcingaException Thrown wen the dataset is not valid for this graph
|
||||||
* @see SVGRenderer::render
|
* @see SVGRenderer::render
|
||||||
*/
|
*/
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
if (!$this->isValidDataFormat()) {
|
if (!$this->isValidDataFormat()) {
|
||||||
throw new Exception('Dataset for graph doesn\'t have the proper structure');
|
throw new IcingaException('Dataset for graph doesn\'t have the proper structure');
|
||||||
}
|
}
|
||||||
$this->build();
|
$this->build();
|
||||||
|
if ($this->align) {
|
||||||
|
$this->renderer->preserveAspectRatio();
|
||||||
|
$this->renderer->setXAspectRatioAlignment(SVGRenderer::X_ASPECT_RATIO_MIN);
|
||||||
|
$this->renderer->setYAspectRatioAlignment(SVGRenderer::Y_ASPECT_RATIO_MIN);
|
||||||
|
}
|
||||||
$this->renderer->getCanvas()->addElement($this);
|
$this->renderer->getCanvas()->addElement($this);
|
||||||
return $this->renderer->render();
|
return $this->renderer->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Align the chart to the top left corner instead of centering it
|
||||||
|
*
|
||||||
|
* @param bool $align
|
||||||
|
*/
|
||||||
|
public function alignTopLeft ($align = true)
|
||||||
|
{
|
||||||
|
$this->align = $align;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,13 @@ use Icinga\Chart\Render\RenderContext;
|
|||||||
*/
|
*/
|
||||||
class BarGraph extends Styleable implements Drawable
|
class BarGraph extends Styleable implements Drawable
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The dataset order
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $order = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the bars.
|
* The width of the bars.
|
||||||
*
|
*
|
||||||
@ -30,14 +37,37 @@ class BarGraph extends Styleable implements Drawable
|
|||||||
*/
|
*/
|
||||||
private $dataSet;
|
private $dataSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tooltips
|
||||||
|
*
|
||||||
|
* @var
|
||||||
|
*/
|
||||||
|
private $tooltips;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All graphs
|
||||||
|
*
|
||||||
|
* @var
|
||||||
|
*/
|
||||||
|
private $graphs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new BarGraph with the given dataset
|
* Create a new BarGraph with the given dataset
|
||||||
*
|
*
|
||||||
* @param array $dataSet An array of datapoints
|
* @param array $dataSet An array of data points
|
||||||
|
* @param int $order The graph number displayed by this BarGraph
|
||||||
|
* @param array $tooltips The tooltips to display for each value
|
||||||
*/
|
*/
|
||||||
public function __construct(array $dataSet)
|
public function __construct(
|
||||||
{
|
array $dataSet,
|
||||||
|
array &$graphs,
|
||||||
|
$order,
|
||||||
|
array $tooltips = null
|
||||||
|
) {
|
||||||
|
$this->order = $order;
|
||||||
$this->dataSet = $dataSet;
|
$this->dataSet = $dataSet;
|
||||||
|
$this->tooltips = $tooltips;
|
||||||
|
$this->graphs = $graphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,6 +86,30 @@ class BarGraph extends Styleable implements Drawable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a single rectangle
|
||||||
|
*
|
||||||
|
* @param array $point The
|
||||||
|
* @param null $index
|
||||||
|
* @param string $fill The fill color to use
|
||||||
|
* @param $strokeWidth
|
||||||
|
*
|
||||||
|
* @return Rect
|
||||||
|
*/
|
||||||
|
private function drawSingleBar($point, $index = null, $fill, $strokeWidth)
|
||||||
|
{
|
||||||
|
$rect = new Rect($point[0] - ($this->barWidth / 2), $point[1], $this->barWidth, 100 - $point[1]);
|
||||||
|
$rect->setFill($fill);
|
||||||
|
$rect->setStrokeWidth($strokeWidth);
|
||||||
|
$rect->setStrokeColor('black');
|
||||||
|
if (isset($index)) {
|
||||||
|
$rect->setAttribute('data-icinga-graph-index', $index);
|
||||||
|
}
|
||||||
|
$rect->setAttribute('data-icinga-graph-type', 'bar');
|
||||||
|
$rect->setAdditionalStyle('clip-path: url(#clip);');
|
||||||
|
return $rect;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render this BarChart
|
* Render this BarChart
|
||||||
*
|
*
|
||||||
@ -68,23 +122,33 @@ class BarGraph extends Styleable implements Drawable
|
|||||||
$doc = $ctx->getDocument();
|
$doc = $ctx->getDocument();
|
||||||
$group = $doc->createElement('g');
|
$group = $doc->createElement('g');
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
foreach ($this->dataSet as $point) {
|
foreach ($this->dataSet as $x => $point) {
|
||||||
$rect = new Rect($point[0] - 2, $point[1], 4, 100 - $point[1]);
|
// add white background bar, to prevent other bars from altering transparency effects
|
||||||
$rect->setFill($this->fill);
|
$bar = $this->drawSingleBar($point, $idx++, 'white', $this->strokeWidth, $idx)->toSvg($ctx);
|
||||||
$rect->setStrokeWidth($this->strokeWidth);
|
$group->appendChild($bar);
|
||||||
$rect->setStrokeColor('black');
|
|
||||||
$rect->setAttribute('data-icinga-graph-index', $idx++);
|
// draw actual bar
|
||||||
$rect->setAttribute('data-icinga-graph-type', 'bar');
|
$bar = $this->drawSingleBar($point, null, $this->fill, $this->strokeWidth, $idx)->toSvg($ctx);
|
||||||
$rect->setAdditionalStyle('clip-path: url(#clip);');
|
$bar->setAttribute('class', 'chart-data');
|
||||||
/*$rect->setAnimation(
|
if (isset($this->tooltips[$x])) {
|
||||||
new Animation(
|
$data = array(
|
||||||
'y',
|
'label' => isset($this->graphs[$this->order]['label']) ?
|
||||||
$ctx->yToAbsolute(100),
|
strtolower($this->graphs[$this->order]['label']) : '',
|
||||||
$ctx->yToAbsolute($point[1]),
|
'color' => isset($this->graphs[$this->order]['color']) ?
|
||||||
rand(1, 1.5)/2
|
strtolower($this->graphs[$this->order]['color']) : '#fff'
|
||||||
)
|
);
|
||||||
);*/
|
$format = isset($this->graphs[$this->order]['tooltip'])
|
||||||
$group->appendChild($rect->toSvg($ctx));
|
? $this->graphs[$this->order]['tooltip'] : null;
|
||||||
|
$bar->setAttribute(
|
||||||
|
'title',
|
||||||
|
$this->tooltips[$x]->renderNoHtml($this->order, $data, $format)
|
||||||
|
);
|
||||||
|
$bar->setAttribute(
|
||||||
|
'data-title-rich',
|
||||||
|
$this->tooltips[$x]->render($this->order, $data, $format)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$group->appendChild($bar);
|
||||||
}
|
}
|
||||||
return $group;
|
return $group;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,10 @@ class StackedGraph implements Drawable
|
|||||||
if (!isset($this->points[$x])) {
|
if (!isset($this->points[$x])) {
|
||||||
$this->points[$x] = 0;
|
$this->points[$x] = 0;
|
||||||
}
|
}
|
||||||
|
// store old y-value for displaying the actual (non-aggregated)
|
||||||
|
// value in the tooltip
|
||||||
|
$point[2] = $point[1];
|
||||||
|
|
||||||
$this->points[$x] += $point[1];
|
$this->points[$x] += $point[1];
|
||||||
$point[1] = $this->points[$x];
|
$point[1] = $this->points[$x];
|
||||||
}
|
}
|
||||||
|
144
library/Icinga/Chart/Graph/Tooltip.php
Normal file
144
library/Icinga/Chart/Graph/Tooltip.php
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<?php
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
|
namespace Icinga\Chart\Graph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tooltip that stores and aggregates information about displayed data
|
||||||
|
* points of a graph and replaces them in a format string to render the description
|
||||||
|
* for specific data points of the graph.
|
||||||
|
*
|
||||||
|
* When render() is called, placeholders for the keys for each data entry will be replaced by
|
||||||
|
* the current value of this data set and the formatted string will be returned.
|
||||||
|
* The content of the replaced keys can change for each data set and depends on how the data
|
||||||
|
* is passed to this class. There are several types of properties:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>Global properties</li>: Key-value pairs that stay the same every time render is called, and are
|
||||||
|
* passed to an instance in the constructor.
|
||||||
|
* <li>Aggregated properties</li>: Global properties that are created automatically from
|
||||||
|
* all attached data points.
|
||||||
|
* <li>Local properties</li>: Key-value pairs that only apply to a single data point and
|
||||||
|
* are passed to the render-function.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
class Tooltip
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The default format string used
|
||||||
|
* when no other format is specified
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $defaultFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All aggregated points
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $points = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains all static replacements
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $data = array(
|
||||||
|
'sum' => 0
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to format the displayed tooltip.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $tooltipFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new tooltip with the specified default format string
|
||||||
|
*
|
||||||
|
* Allows you to set the global data for this tooltip, that is displayed every
|
||||||
|
* time render is called.
|
||||||
|
*
|
||||||
|
* @param array $data Map of global properties
|
||||||
|
* @param string $format The default format string
|
||||||
|
*/
|
||||||
|
public function __construct (
|
||||||
|
$data = array(),
|
||||||
|
$format = '<b>{title}</b></b><br/> {value} of {sum} {label}'
|
||||||
|
) {
|
||||||
|
$this->data = array_merge($this->data, $data);
|
||||||
|
$this->defaultFormat = $format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single data point to update the aggregated properties for this tooltip
|
||||||
|
*
|
||||||
|
* @param $point array Contains the (x,y) values of the data set
|
||||||
|
*/
|
||||||
|
public function addDataPoint($point)
|
||||||
|
{
|
||||||
|
// set x-value
|
||||||
|
if (!isset($this->data['title'])) {
|
||||||
|
$this->data['title'] = $point[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// aggregate y-values
|
||||||
|
$y = (int)$point[1];
|
||||||
|
if (isset($point[2])) {
|
||||||
|
// load original value in case value already aggregated
|
||||||
|
$y = (int)$point[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($this->data['min']) || $this->data['min'] > $y) {
|
||||||
|
$this->data['min'] = $y;
|
||||||
|
}
|
||||||
|
if (!isset($this->data['max']) || $this->data['max'] < $y) {
|
||||||
|
$this->data['max'] = $y;
|
||||||
|
}
|
||||||
|
$this->data['sum'] += $y;
|
||||||
|
$this->points[] = $y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the tooltip for a certain data point
|
||||||
|
*
|
||||||
|
* @param array $order Which data set to render
|
||||||
|
* @param array $data The local data for this tooltip
|
||||||
|
* @param string $format Use a custom format string for this data set
|
||||||
|
*
|
||||||
|
* @return mixed|string The tooltip value
|
||||||
|
*/
|
||||||
|
public function render($order, $data = array(), $format = null)
|
||||||
|
{
|
||||||
|
if (isset($format)) {
|
||||||
|
$str = $format;
|
||||||
|
} else {
|
||||||
|
$str = $this->defaultFormat;
|
||||||
|
}
|
||||||
|
$data['value'] = $this->points[$order];
|
||||||
|
foreach (array_merge($this->data, $data) as $key => $value) {
|
||||||
|
$str = str_replace('{' . $key . '}', $value, $str);
|
||||||
|
}
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the tooltip for a certain data point but remove all
|
||||||
|
* occurring html tags
|
||||||
|
*
|
||||||
|
* This is useful for rendering clean tooltips on client without JavaScript
|
||||||
|
*
|
||||||
|
* @param array $order Which data set to render
|
||||||
|
* @param array $data The local data for this tooltip
|
||||||
|
* @param string $format Use a custom format string for this data set
|
||||||
|
*
|
||||||
|
* @return mixed|string The tooltip value, without any HTML tags
|
||||||
|
*/
|
||||||
|
public function renderNoHtml($order, $data, $format)
|
||||||
|
{
|
||||||
|
return strip_tags($this->render($order, $data, $format));
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ use Icinga\Chart\Axis;
|
|||||||
use Icinga\Chart\Graph\BarGraph;
|
use Icinga\Chart\Graph\BarGraph;
|
||||||
use Icinga\Chart\Graph\LineGraph;
|
use Icinga\Chart\Graph\LineGraph;
|
||||||
use Icinga\Chart\Graph\StackedGraph;
|
use Icinga\Chart\Graph\StackedGraph;
|
||||||
|
use Icinga\Chart\Graph\Tooltip;
|
||||||
use Icinga\Chart\Primitive\Canvas;
|
use Icinga\Chart\Primitive\Canvas;
|
||||||
use Icinga\Chart\Primitive\Rect;
|
use Icinga\Chart\Primitive\Rect;
|
||||||
use Icinga\Chart\Primitive\Path;
|
use Icinga\Chart\Primitive\Path;
|
||||||
@ -74,6 +75,16 @@ class GridChart extends Chart
|
|||||||
*/
|
*/
|
||||||
private $stacks = array();
|
private $stacks = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An associative array containing all Tooltips used to render the titles
|
||||||
|
*
|
||||||
|
* Each tooltip represents the summary for all y-values of a certain x-value
|
||||||
|
* in the grid chart
|
||||||
|
*
|
||||||
|
* @var Tooltip
|
||||||
|
*/
|
||||||
|
private $tooltips = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current dataset has the proper structure for this chart.
|
* Check if the current dataset has the proper structure for this chart.
|
||||||
*
|
*
|
||||||
@ -169,6 +180,26 @@ class GridChart extends Chart
|
|||||||
$this->legend->addDataset($graph);
|
$this->legend->addDataset($graph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->initTooltips($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function initTooltips($data)
|
||||||
|
{
|
||||||
|
foreach ($data as &$graph) {
|
||||||
|
foreach ($graph['data'] as $x => $point) {
|
||||||
|
if (!array_key_exists($x, $this->tooltips)) {
|
||||||
|
$this->tooltips[$x] = new Tooltip(
|
||||||
|
array(
|
||||||
|
'color' => $graph['color'],
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->tooltips[$x]->addDataPoint($point);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -353,11 +384,16 @@ class GridChart extends Chart
|
|||||||
foreach ($this->graphs as $axisName => $graphs) {
|
foreach ($this->graphs as $axisName => $graphs) {
|
||||||
$axis = $this->axis[$axisName];
|
$axis = $this->axis[$axisName];
|
||||||
$graphObj = null;
|
$graphObj = null;
|
||||||
foreach ($graphs as $graph) {
|
foreach ($graphs as $dataset => $graph) {
|
||||||
// determine the type and create a graph object for it
|
// determine the type and create a graph object for it
|
||||||
switch ($graph['graphType']) {
|
switch ($graph['graphType']) {
|
||||||
case self::TYPE_BAR:
|
case self::TYPE_BAR:
|
||||||
$graphObj = new BarGraph($axis->transform($graph['data']));
|
$graphObj = new BarGraph(
|
||||||
|
$axis->transform($graph['data']),
|
||||||
|
$graphs,
|
||||||
|
$dataset,
|
||||||
|
$this->tooltips
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case self::TYPE_LINE:
|
case self::TYPE_LINE:
|
||||||
$graphObj = new LineGraph($axis->transform($graph['data']));
|
$graphObj = new LineGraph($axis->transform($graph['data']));
|
||||||
|
@ -7,6 +7,7 @@ namespace Icinga\Chart\Inline;
|
|||||||
use Icinga\Chart\PieChart as PieChartRenderer;
|
use Icinga\Chart\PieChart as PieChartRenderer;
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw an inline pie-chart directly from the available request parameters.
|
* Draw an inline pie-chart directly from the available request parameters.
|
||||||
@ -17,11 +18,11 @@ class PieChart extends Inline
|
|||||||
public function render($output = true)
|
public function render($output = true)
|
||||||
{
|
{
|
||||||
$pie = new PieChartRenderer();
|
$pie = new PieChartRenderer();
|
||||||
|
$pie->alignTopLeft();
|
||||||
$pie->disableLegend();
|
$pie->disableLegend();
|
||||||
$pie->drawPie(array(
|
$pie->drawPie(array(
|
||||||
'data' => $this->data, 'colors' => $this->colors, 'labels' => $this->labels
|
'data' => $this->data, 'colors' => $this->colors, 'labels' => $this->labels
|
||||||
));
|
));
|
||||||
$pie->setWidth($this->width)->setHeight($this->height);
|
|
||||||
if ($output) {
|
if ($output) {
|
||||||
echo $pie->render();
|
echo $pie->render();
|
||||||
} else {
|
} else {
|
||||||
@ -33,7 +34,7 @@ class PieChart extends Inline
|
|||||||
{
|
{
|
||||||
if (! class_exists('Imagick')) {
|
if (! class_exists('Imagick')) {
|
||||||
// TODO: This is quick & dirty. 404?
|
// TODO: This is quick & dirty. 404?
|
||||||
throw new Exception('Cannot render PNGs without Imagick');
|
throw new IcingaException('Cannot render PNGs without Imagick');
|
||||||
}
|
}
|
||||||
$image = new Imagick();
|
$image = new Imagick();
|
||||||
$image->readImageBlob($this->render(false));
|
$image->readImageBlob($this->render(false));
|
||||||
|
@ -16,7 +16,7 @@ use Icinga\Chart\Render\LayoutBox;
|
|||||||
/**
|
/**
|
||||||
* Graphing component for rendering Pie Charts.
|
* Graphing component for rendering Pie Charts.
|
||||||
*
|
*
|
||||||
* See the graphs.md documentation for futher information about how to use this component
|
* See the graphs.md documentation for further information about how to use this component
|
||||||
*/
|
*/
|
||||||
class PieChart extends Chart
|
class PieChart extends Chart
|
||||||
{
|
{
|
||||||
@ -51,46 +51,6 @@ class PieChart extends Chart
|
|||||||
*/
|
*/
|
||||||
private $noCaption = false;
|
private $noCaption = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Scaling level of the rendered svgs width in percent.
|
|
||||||
*
|
|
||||||
* @var float
|
|
||||||
*/
|
|
||||||
private $width = 100;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scaling level of the rendered svgs height in percent.
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $height = 100;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the size of the rendered pie-chart svg.
|
|
||||||
*
|
|
||||||
* @param $width int The width in percent.
|
|
||||||
*
|
|
||||||
* @return self Fluent interface
|
|
||||||
*/
|
|
||||||
public function setWidth($width)
|
|
||||||
{
|
|
||||||
$this->width = $width;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the size of the rendered pie-chart svg.
|
|
||||||
*
|
|
||||||
* @param $height int The height in percent.
|
|
||||||
*
|
|
||||||
* @return self Fluent interface
|
|
||||||
*/
|
|
||||||
public function setHeight($height)
|
|
||||||
{
|
|
||||||
$this->height = $height;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the given pies have the correct format
|
* Test if the given pies have the correct format
|
||||||
*
|
*
|
||||||
@ -111,10 +71,7 @@ class PieChart extends Chart
|
|||||||
*/
|
*/
|
||||||
protected function build()
|
protected function build()
|
||||||
{
|
{
|
||||||
$this->renderer = new SVGRenderer(
|
$this->renderer = new SVGRenderer(($this->type === self::STACKED) ? 1 : count($this->pies), 1);
|
||||||
$this->type === self::STACKED ? $this->width : count($this->pies) * $this->width,
|
|
||||||
$this->width
|
|
||||||
);
|
|
||||||
foreach ($this->pies as &$pie) {
|
foreach ($this->pies as &$pie) {
|
||||||
$this->normalizeDataSet($pie);
|
$this->normalizeDataSet($pie);
|
||||||
}
|
}
|
||||||
@ -165,11 +122,16 @@ class PieChart extends Chart
|
|||||||
*/
|
*/
|
||||||
public function toSvg(RenderContext $ctx)
|
public function toSvg(RenderContext $ctx)
|
||||||
{
|
{
|
||||||
$outerBox = new Canvas('outerGraph', new LayoutBox(0, 0, 100, 100));
|
|
||||||
$innerBox = new Canvas('graph', new LayoutBox(0, 0, 100, 100));
|
|
||||||
$labelBox = $ctx->getDocument()->createElement('g');
|
$labelBox = $ctx->getDocument()->createElement('g');
|
||||||
if (!$this->noCaption) {
|
if (!$this->noCaption) {
|
||||||
|
// Scale SVG to make room for captions
|
||||||
|
$outerBox = new Canvas('outerGraph', new LayoutBox(33, -5, 40, 40));
|
||||||
|
$innerBox = new Canvas('graph', new LayoutBox(0, 0, 100, 100));
|
||||||
$innerBox->getLayout()->setPadding(10, 10, 10, 10);
|
$innerBox->getLayout()->setPadding(10, 10, 10, 10);
|
||||||
|
} else {
|
||||||
|
$outerBox = new Canvas('outerGraph', new LayoutBox(1.5, -10, 124, 124));
|
||||||
|
$innerBox = new Canvas('graph', new LayoutBox(0, 0, 100, 100));
|
||||||
|
$innerBox->getLayout()->setPadding(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
$this->createContentClipBox($innerBox);
|
$this->createContentClipBox($innerBox);
|
||||||
$this->renderPies($innerBox, $labelBox);
|
$this->renderPies($innerBox, $labelBox);
|
||||||
@ -274,9 +236,6 @@ class PieChart extends Chart
|
|||||||
$lastRadius = 0;
|
$lastRadius = 0;
|
||||||
foreach ($pie['data'] as $idx => $dataset) {
|
foreach ($pie['data'] as $idx => $dataset) {
|
||||||
$color = $this->getColorForPieSlice($pie, $idx);
|
$color = $this->getColorForPieSlice($pie, $idx);
|
||||||
if ($dataset === 100) {
|
|
||||||
$dataset = 99.9;
|
|
||||||
}
|
|
||||||
if ($dataset == 0) {
|
if ($dataset == 0) {
|
||||||
$labelPos++;
|
$labelPos++;
|
||||||
continue;
|
continue;
|
||||||
@ -340,3 +299,4 @@ class PieChart extends Chart
|
|||||||
$clipBox->addElement($rect);
|
$clipBox->addElement($rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class PieSlice extends Animatable implements Drawable
|
|||||||
*
|
*
|
||||||
* @var float
|
* @var float
|
||||||
*/
|
*/
|
||||||
private $endRadian= 0;
|
private $endRadian = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The x position of the pie slice's center
|
* The x position of the pie slice's center
|
||||||
@ -104,17 +104,21 @@ class PieSlice extends Animatable implements Drawable
|
|||||||
*/
|
*/
|
||||||
private function getPieSlicePath($x, $y, $r)
|
private function getPieSlicePath($x, $y, $r)
|
||||||
{
|
{
|
||||||
// start at the center of the pieslice
|
|
||||||
$pathString = 'M ' . $x . ' ' . $y . ' ';
|
|
||||||
|
|
||||||
// The coordinate system is mirrored on the Y axis, so we have to flip cos and sin
|
// The coordinate system is mirrored on the Y axis, so we have to flip cos and sin
|
||||||
$xStart = $x + ($r * sin($this->startRadian));
|
$xStart = $x + ($r * sin($this->startRadian));
|
||||||
$yStart = $y - ($r * cos($this->startRadian));
|
$yStart = $y - ($r * cos($this->startRadian));
|
||||||
$xEnd = $x + ($r * sin($this->endRadian));
|
|
||||||
$yEnd = $y - ($r * cos($this->endRadian));
|
|
||||||
|
|
||||||
|
if ($this->endRadian - $this->startRadian == 2*M_PI) {
|
||||||
|
// To draw a full circle, adjust arc endpoint by a small (unvisible) value
|
||||||
|
$this->endRadian -= 0.001;
|
||||||
|
$pathString = 'M ' . Format::formatSVGNumber($xStart) . ' ' . Format::formatSVGNumber($yStart);
|
||||||
|
} else {
|
||||||
|
// Start at the center of the pieslice
|
||||||
|
$pathString = 'M ' . $x . ' ' . $y;
|
||||||
// Draw a straight line to the upper part of the arc
|
// Draw a straight line to the upper part of the arc
|
||||||
$pathString .= 'L ' . Format::formatSVGNumber($xStart) . ' ' . Format::formatSVGNumber($yStart);
|
$pathString .= ' L ' . Format::formatSVGNumber($xStart) . ' ' . Format::formatSVGNumber($yStart);
|
||||||
|
}
|
||||||
|
|
||||||
// Instead of directly connecting the upper part of the arc (leaving a triangle), draw a bow with the radius
|
// Instead of directly connecting the upper part of the arc (leaving a triangle), draw a bow with the radius
|
||||||
$pathString .= ' A ' . Format::formatSVGNumber($r) . ' ' . Format::formatSVGNumber($r);
|
$pathString .= ' A ' . Format::formatSVGNumber($r) . ' ' . Format::formatSVGNumber($r);
|
||||||
// These are the flags for the bow, see the SVG path documentation for details
|
// These are the flags for the bow, see the SVG path documentation for details
|
||||||
@ -122,7 +126,10 @@ class PieSlice extends Animatable implements Drawable
|
|||||||
$pathString .= ' 0 ' . (($this->endRadian - $this->startRadian > M_PI) ? '1' : '0 ') . ' 1';
|
$pathString .= ' 0 ' . (($this->endRadian - $this->startRadian > M_PI) ? '1' : '0 ') . ' 1';
|
||||||
|
|
||||||
// xEnd and yEnd are the lower point of the arc
|
// xEnd and yEnd are the lower point of the arc
|
||||||
|
$xEnd = $x + ($r * sin($this->endRadian));
|
||||||
|
$yEnd = $y - ($r * cos($this->endRadian));
|
||||||
$pathString .= ' ' . Format::formatSVGNumber($xEnd) . ' ' . Format::formatSVGNumber($yEnd);
|
$pathString .= ' ' . Format::formatSVGNumber($xEnd) . ' ' . Format::formatSVGNumber($yEnd);
|
||||||
|
|
||||||
return $pathString;
|
return $pathString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +159,7 @@ class PieSlice extends Animatable implements Drawable
|
|||||||
// Draw the handle
|
// Draw the handle
|
||||||
$path = new Path(array($midX, $midY));
|
$path = new Path(array($midX, $midY));
|
||||||
|
|
||||||
$midX += ($addOffset + $r/1.8) * ($midRadius > M_PI ? -1 : 1);
|
$midX += ($addOffset + $r/3) * ($midRadius > M_PI ? -1 : 1);
|
||||||
$path->append(array($midX, $midY))->toAbsolute();
|
$path->append(array($midX, $midY))->toAbsolute();
|
||||||
|
|
||||||
$midX += intval($r/2 * sin(M_PI/9)) * ($midRadius > M_PI ? -1 : 1);
|
$midX += intval($r/2 * sin(M_PI/9)) * ($midRadius > M_PI ? -1 : 1);
|
||||||
@ -169,7 +176,7 @@ class PieSlice extends Animatable implements Drawable
|
|||||||
|
|
||||||
// Draw the text box
|
// Draw the text box
|
||||||
$text = new Text($rel[0]+1.5, $rel[1], $this->caption);
|
$text = new Text($rel[0]+1.5, $rel[1], $this->caption);
|
||||||
$text->setFontSize('2.5em');
|
$text->setFontSize('5em');
|
||||||
$text->setAlignment(($midRadius > M_PI ? Text::ALIGN_END : Text::ALIGN_START));
|
$text->setAlignment(($midRadius > M_PI ? Text::ALIGN_END : Text::ALIGN_START));
|
||||||
|
|
||||||
$group->appendChild($path->toSvg($ctx));
|
$group->appendChild($path->toSvg($ctx));
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
namespace Icinga\Chart\Primitive;
|
namespace Icinga\Chart\Primitive;
|
||||||
|
|
||||||
use \DomElement;
|
use DomElement;
|
||||||
use \Icinga\Chart\Render\RenderContext;
|
use Icinga\Chart\Render\RenderContext;
|
||||||
use Icinga\Chart\Format;
|
use Icinga\Chart\Format;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,7 +132,7 @@ class RenderContext
|
|||||||
* @param int $x The relative x coordinate
|
* @param int $x The relative x coordinate
|
||||||
* @param int $y The relative y coordinate
|
* @param int $y The relative y coordinate
|
||||||
*
|
*
|
||||||
* @return array An x,y tupel containing absolute coordinates
|
* @return array An x,y tuple containing absolute coordinates
|
||||||
* @see RenderContext::toRelative
|
* @see RenderContext::toRelative
|
||||||
*/
|
*/
|
||||||
public function toAbsolute($x, $y)
|
public function toAbsolute($x, $y)
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
* Created by PhpStorm.
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
* User: mjentsch
|
|
||||||
* Date: 22.07.14
|
|
||||||
* Time: 10:17
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Icinga\Chart\Render;
|
namespace Icinga\Chart\Render;
|
||||||
|
|
||||||
|
@ -19,6 +19,22 @@ use Icinga\Chart\Primitive\Canvas;
|
|||||||
*/
|
*/
|
||||||
class SVGRenderer
|
class SVGRenderer
|
||||||
{
|
{
|
||||||
|
const X_ASPECT_RATIO_MIN = 'xMin';
|
||||||
|
|
||||||
|
const X_ASPECT_RATIO_MID = 'xMid';
|
||||||
|
|
||||||
|
const X_ASPECT_RATIO_MAX = 'xMax';
|
||||||
|
|
||||||
|
const Y_ASPECT_RATIO_MIN = 'YMin';
|
||||||
|
|
||||||
|
const Y_ASPECT_RATIO_MID = 'YMid';
|
||||||
|
|
||||||
|
const Y_ASPECT_RATIO_MAX = 'YMax';
|
||||||
|
|
||||||
|
const ASPECT_RATIO_PAD = 'meet';
|
||||||
|
|
||||||
|
const ASPECT_RATIO_CUTOFF = 'slice';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The XML-document
|
* The XML-document
|
||||||
*
|
*
|
||||||
@ -54,6 +70,35 @@ class SVGRenderer
|
|||||||
*/
|
*/
|
||||||
private $height = 100;
|
private $height = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the aspect ratio is preversed
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $preserveAspectRatio = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Horizontal alignment of SVG element
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $xAspectRatio = self::X_ASPECT_RATIO_MID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertical alignment of SVG element
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $yAspectRatio = self::Y_ASPECT_RATIO_MID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define whether aspect differences should be handled using padding (default) or cutoff
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $xFillMode = "meet";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the root document and the SVG root node
|
* Create the root document and the SVG root node
|
||||||
*/
|
*/
|
||||||
@ -82,8 +127,8 @@ class SVGRenderer
|
|||||||
$svg = $this->document->createElement('svg');
|
$svg = $this->document->createElement('svg');
|
||||||
$svg->setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
$svg->setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
||||||
$svg->setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
|
$svg->setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
|
||||||
$svg->setAttribute('width', $this->width . '%');
|
$svg->setAttribute('width', '100%');
|
||||||
$svg->setAttribute('height', $this->height . '%');
|
$svg->setAttribute('height', '100%');
|
||||||
$svg->setAttribute(
|
$svg->setAttribute(
|
||||||
'viewBox',
|
'viewBox',
|
||||||
sprintf(
|
sprintf(
|
||||||
@ -92,6 +137,17 @@ class SVGRenderer
|
|||||||
$ctx->getNrOfUnitsY()
|
$ctx->getNrOfUnitsY()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
if ($this->preserveAspectRatio) {
|
||||||
|
$svg->setAttribute(
|
||||||
|
'preserveAspectRatio',
|
||||||
|
sprintf (
|
||||||
|
'%s%s %s',
|
||||||
|
$this->xAspectRatio,
|
||||||
|
$this->yAspectRatio,
|
||||||
|
$this->xFillMode
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
return $svg;
|
return $svg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,4 +197,40 @@ class SVGRenderer
|
|||||||
{
|
{
|
||||||
return $this->rootCanvas;
|
return $this->rootCanvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preserve the aspect ratio of the rendered object
|
||||||
|
*
|
||||||
|
* Do not deform the content of the SVG when the aspect ratio of the viewBox
|
||||||
|
* differs from the aspect ratio of the SVG element, but add padding or cutoff
|
||||||
|
* instead
|
||||||
|
*
|
||||||
|
* @param bool $preserve Whether the aspect ratio should be preserved
|
||||||
|
*/
|
||||||
|
public function preserveAspectRatio($preserve = true)
|
||||||
|
{
|
||||||
|
$this->preserveAspectRatio = $preserve;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the horizontal alignment of the SVG element
|
||||||
|
*
|
||||||
|
* Change the horizontal alignment of the svg, when preserveAspectRatio is used and
|
||||||
|
* padding is present. Defaults to
|
||||||
|
*/
|
||||||
|
public function setXAspectRatioAlignment($alignment)
|
||||||
|
{
|
||||||
|
$this->xAspectRatio = $alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the vertical alignment of the SVG element
|
||||||
|
*
|
||||||
|
* Change the vertical alignment of the svg, when preserveAspectRatio is used and
|
||||||
|
* padding is present.
|
||||||
|
*/
|
||||||
|
public function setYAspectRatioAlignment($alignment)
|
||||||
|
{
|
||||||
|
$this->yAspectRatio = $alignment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
namespace Icinga\Cli;
|
namespace Icinga\Cli;
|
||||||
|
|
||||||
use Icinga\Cli\Screen;
|
use Icinga\Cli\Screen;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
// @see http://en.wikipedia.org/wiki/ANSI_escape_code
|
// @see http://en.wikipedia.org/wiki/ANSI_escape_code
|
||||||
|
|
||||||
@ -74,7 +75,10 @@ class AnsiScreen extends Screen
|
|||||||
protected function fgColor($color)
|
protected function fgColor($color)
|
||||||
{
|
{
|
||||||
if (! array_key_exists($color, $this->fgColors)) {
|
if (! array_key_exists($color, $this->fgColors)) {
|
||||||
throw new \Exception(sprintf('There is no such foreground color: %s', $color));
|
throw new IcingaException(
|
||||||
|
'There is no such foreground color: %s',
|
||||||
|
$color
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return $this->fgColors[$color];
|
return $this->fgColors[$color];
|
||||||
}
|
}
|
||||||
@ -82,7 +86,10 @@ class AnsiScreen extends Screen
|
|||||||
protected function bgColor($color)
|
protected function bgColor($color)
|
||||||
{
|
{
|
||||||
if (! array_key_exists($color, $this->bgColors)) {
|
if (! array_key_exists($color, $this->bgColors)) {
|
||||||
throw new \Exception(sprintf('There is no such background color: %s', $color));
|
throw new IcingaException(
|
||||||
|
'There is no such background color: %s',
|
||||||
|
$color
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return $this->bgColors[$color];
|
return $this->bgColors[$color];
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ use Icinga\Cli\Params;
|
|||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Application\ApplicationBootstrap as App;
|
use Icinga\Application\ApplicationBootstrap as App;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
abstract class Command
|
abstract class Command
|
||||||
{
|
{
|
||||||
@ -123,7 +124,7 @@ abstract class Command
|
|||||||
|
|
||||||
public function fail($msg)
|
public function fail($msg)
|
||||||
{
|
{
|
||||||
throw new Exception($msg);
|
throw new IcingaException('%s', $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultActionName()
|
public function getDefaultActionName()
|
||||||
|
@ -332,7 +332,8 @@ class Loader
|
|||||||
{
|
{
|
||||||
if (! $this->hasModule($module)) {
|
if (! $this->hasModule($module)) {
|
||||||
throw new ProgrammingError(
|
throw new ProgrammingError(
|
||||||
sprintf('There is no such module: %s', $module)
|
'There is no such module: %s',
|
||||||
|
$module
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,7 +342,8 @@ class Loader
|
|||||||
{
|
{
|
||||||
if (! $this->hasCommand($command)) {
|
if (! $this->hasCommand($command)) {
|
||||||
throw new ProgrammingError(
|
throw new ProgrammingError(
|
||||||
sprintf('There is no such command: %s', $command)
|
'There is no such command: %s',
|
||||||
|
$command
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,7 +353,9 @@ class Loader
|
|||||||
$this->assertModuleExists($module);
|
$this->assertModuleExists($module);
|
||||||
if (! $this->hasModuleCommand($module, $command)) {
|
if (! $this->hasModuleCommand($module, $command)) {
|
||||||
throw new ProgrammingError(
|
throw new ProgrammingError(
|
||||||
sprintf("The module '%s' has no such command: %s", $module, $command)
|
'The module \'%s\' has no such command: %s',
|
||||||
|
$module,
|
||||||
|
$command
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,45 @@ class PreservingIniWriter extends Zend_Config_Writer_FileAbstract
|
|||||||
parent::__construct($options);
|
parent::__construct($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all keys containing dots and convert it to a nested configuration
|
||||||
|
*
|
||||||
|
* Ensure that configurations with the same ini representation the have
|
||||||
|
* similarly nested Zend_Config objects. The configuration may be altered
|
||||||
|
* during that process.
|
||||||
|
*
|
||||||
|
* @param Zend_Config $config The configuration to normalize
|
||||||
|
* @return Zend_Config The normalized config
|
||||||
|
*/
|
||||||
|
private function normalizeKeys(Zend_Config $config)
|
||||||
|
{
|
||||||
|
foreach ($config as $key => $value) {
|
||||||
|
if (preg_match('/\./', $key) > 0) {
|
||||||
|
// remove old key
|
||||||
|
unset ($config->$key);
|
||||||
|
|
||||||
|
// insert new key
|
||||||
|
$nests = explode('.', $key);
|
||||||
|
$current = $config;
|
||||||
|
$i = 0;
|
||||||
|
for (; $i < count($nests) - 1; $i++) {
|
||||||
|
if (! isset($current->{$nests[$i]})) {
|
||||||
|
// configuration key doesn't exist, create a new nesting level
|
||||||
|
$current->{$nests[$i]} = new Zend_Config (array(), true);
|
||||||
|
}
|
||||||
|
// move to next nesting level
|
||||||
|
$current = $current->{$nests[$i]};
|
||||||
|
}
|
||||||
|
// reached last nesting level, insert value
|
||||||
|
$current->{$nests[$i]} = $value;
|
||||||
|
}
|
||||||
|
if ($value instanceof Zend_Config) {
|
||||||
|
$config->$key = $this->normalizeKeys ($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the Zend_Config into a config file string
|
* Render the Zend_Config into a config file string
|
||||||
*
|
*
|
||||||
@ -50,6 +89,17 @@ class PreservingIniWriter extends Zend_Config_Writer_FileAbstract
|
|||||||
} else {
|
} else {
|
||||||
$oldconfig = new Zend_Config(array());
|
$oldconfig = new Zend_Config(array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create an internal copy of the given configuration, since the user of this class
|
||||||
|
// won't expect that a configuration will ever be altered during
|
||||||
|
// the rendering process.
|
||||||
|
$extends = $this->_config->getExtends();
|
||||||
|
$this->_config = new Zend_Config ($this->_config->toArray(), true);
|
||||||
|
foreach ($extends as $extending => $extended) {
|
||||||
|
$this->_config->setExtend($extending, $extended);
|
||||||
|
}
|
||||||
|
$this->_config = $this->normalizeKeys($this->_config);
|
||||||
|
|
||||||
$newconfig = $this->_config;
|
$newconfig = $this->_config;
|
||||||
$editor = new IniEditor(file_get_contents($this->_filename), $this->options);
|
$editor = new IniEditor(file_get_contents($this->_filename), $this->options);
|
||||||
$this->diffConfigs($oldconfig, $newconfig, $editor);
|
$this->diffConfigs($oldconfig, $newconfig, $editor);
|
||||||
|
@ -142,7 +142,10 @@ class DbConnection implements Selectable
|
|||||||
}
|
}
|
||||||
break;*/
|
break;*/
|
||||||
default:
|
default:
|
||||||
throw new ConfigurationError(sprintf('Backend "%s" is not supported', $this->dbType));
|
throw new ConfigurationError(
|
||||||
|
'Backend "%s" is not supported',
|
||||||
|
$this->dbType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$this->dbAdapter = Zend_Db::factory($adapter, $adapterParamaters);
|
$this->dbAdapter = Zend_Db::factory($adapter, $adapterParamaters);
|
||||||
$this->dbAdapter->setFetchMode(Zend_Db::FETCH_OBJ);
|
$this->dbAdapter->setFetchMode(Zend_Db::FETCH_OBJ);
|
||||||
|
@ -11,6 +11,7 @@ use Icinga\Data\Filter\FilterExpression;
|
|||||||
use Icinga\Data\Filter\FilterOr;
|
use Icinga\Data\Filter\FilterOr;
|
||||||
use Icinga\Data\Filter\FilterAnd;
|
use Icinga\Data\Filter\FilterAnd;
|
||||||
use Icinga\Data\Filter\FilterNot;
|
use Icinga\Data\Filter\FilterNot;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
use Zend_Db_Select;
|
use Zend_Db_Select;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,6 +89,17 @@ class DbQuery extends SimpleQuery
|
|||||||
public function getSelectQuery()
|
public function getSelectQuery()
|
||||||
{
|
{
|
||||||
$select = $this->dbSelect();
|
$select = $this->dbSelect();
|
||||||
|
|
||||||
|
// Add order fields to select for postgres distinct queries (#6351)
|
||||||
|
if ($this->hasOrder()
|
||||||
|
&& $this->getDatasource()->getDbType() === 'pgsql'
|
||||||
|
&& $select->getPart(Zend_Db_Select::DISTINCT) === true) {
|
||||||
|
foreach ($this->getOrder() as $fieldAndDirection) {
|
||||||
|
list($alias, $field) = explode('.', $fieldAndDirection[0]);
|
||||||
|
$this->columns[$field] = $fieldAndDirection[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$select->columns($this->columns);
|
$select->columns($this->columns);
|
||||||
$this->applyFilterSql($select);
|
$this->applyFilterSql($select);
|
||||||
|
|
||||||
@ -101,6 +113,7 @@ class DbQuery extends SimpleQuery
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $select;
|
return $select;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +137,10 @@ class DbQuery extends SimpleQuery
|
|||||||
$op = ' AND ';
|
$op = ' AND ';
|
||||||
$str .= ' NOT ';
|
$str .= ' NOT ';
|
||||||
} else {
|
} else {
|
||||||
throw new \Exception('Cannot render filter: ' . $filter);
|
throw new IcingaException(
|
||||||
|
'Cannot render filter: %s',
|
||||||
|
$filter
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$parts = array();
|
$parts = array();
|
||||||
if (! $filter->isEmpty()) {
|
if (! $filter->isEmpty()) {
|
||||||
@ -177,7 +193,7 @@ class DbQuery extends SimpleQuery
|
|||||||
if (! $value) {
|
if (! $value) {
|
||||||
/*
|
/*
|
||||||
NOTE: It's too late to throw exceptions, we might finish in __toString
|
NOTE: It's too late to throw exceptions, we might finish in __toString
|
||||||
throw new \Exception(sprintf(
|
throw new IcingaException(sprintf(
|
||||||
'"%s" is not a valid time expression',
|
'"%s" is not a valid time expression',
|
||||||
$value
|
$value
|
||||||
));
|
));
|
||||||
|
@ -34,9 +34,12 @@ abstract class Filter
|
|||||||
if ((string) $id === $this->getId()) {
|
if ((string) $id === $this->getId()) {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
throw new ProgrammingError(sprintf(
|
throw new ProgrammingError(
|
||||||
'Trying to get invalid filter index "%s" from "%s" ("%s")', $id, $this, $this->id
|
'Trying to get invalid filter index "%s" from "%s" ("%s")',
|
||||||
));
|
$id,
|
||||||
|
$this,
|
||||||
|
$this->id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId()
|
public function getId()
|
||||||
@ -129,14 +132,15 @@ abstract class Filter
|
|||||||
public static function expression($col, $op, $expression)
|
public static function expression($col, $op, $expression)
|
||||||
{
|
{
|
||||||
switch ($op) {
|
switch ($op) {
|
||||||
case '=': return new FilterEqual($col, $op, $expression);
|
case '=': return new FilterMatch($col, $op, $expression);
|
||||||
case '<': return new FilterLessThan($col, $op, $expression);
|
case '<': return new FilterLessThan($col, $op, $expression);
|
||||||
case '>': return new FilterGreaterThan($col, $op, $expression);
|
case '>': return new FilterGreaterThan($col, $op, $expression);
|
||||||
case '>=': return new FilterEqualOrGreaterThan($col, $op, $expression);
|
case '>=': return new FilterEqualOrGreaterThan($col, $op, $expression);
|
||||||
case '<=': return new FilterEqualOrLessThan($col, $op, $expression);
|
case '<=': return new FilterEqualOrLessThan($col, $op, $expression);
|
||||||
case '!=': return new FilterNotEqual($col, $op, $expression);
|
case '!=': return new FilterMatchNot($col, $op, $expression);
|
||||||
default: throw new ProgrammingError(
|
default: throw new ProgrammingError(
|
||||||
sprintf('There is no such filter sign: %s', $op)
|
'There is no such filter sign: %s',
|
||||||
|
$op
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +207,8 @@ abstract class Filter
|
|||||||
case 'NOT': return self::not($filters);
|
case 'NOT': return self::not($filters);
|
||||||
}
|
}
|
||||||
throw new ProgrammingError(
|
throw new ProgrammingError(
|
||||||
sprintf('"%s" is not a valid filter chain operator', $operator)
|
'"%s" is not a valid filter chain operator',
|
||||||
|
$operator
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
namespace Icinga\Data\Filter;
|
namespace Icinga\Data\Filter;
|
||||||
|
|
||||||
use Exception;
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter Exception Class
|
* Filter Exception Class
|
||||||
*
|
*
|
||||||
* Filter Exceptions should be thrown on filter parse errors or similar
|
* Filter Exceptions should be thrown on filter parse errors or similar
|
||||||
*/
|
*/
|
||||||
class FilterException extends Exception {}
|
class FilterException extends IcingaException {}
|
||||||
|
22
library/Icinga/Data/Filter/FilterMatch.php
Normal file
22
library/Icinga/Data/Filter/FilterMatch.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
|
namespace Icinga\Data\Filter;
|
||||||
|
|
||||||
|
class FilterMatch extends FilterExpression
|
||||||
|
{
|
||||||
|
public function matches($row)
|
||||||
|
{
|
||||||
|
$expression = (string) $this->expression;
|
||||||
|
if (strpos($expression, '*') === false) {
|
||||||
|
return (string) $row->{$this->column} === $expression;
|
||||||
|
} else {
|
||||||
|
$parts = array();
|
||||||
|
foreach (preg_split('/\*/', $expression) as $part) {
|
||||||
|
$parts[] = preg_quote($part);
|
||||||
|
}
|
||||||
|
return preg_match('/^' . implode('.*', $parts) . '$/', $row->{$this->column});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
library/Icinga/Data/Filter/FilterMatchNot.php
Normal file
22
library/Icinga/Data/Filter/FilterMatchNot.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
|
namespace Icinga\Data\Filter;
|
||||||
|
|
||||||
|
class FilterMatchNot extends FilterExpression
|
||||||
|
{
|
||||||
|
public function matches($row)
|
||||||
|
{
|
||||||
|
$expression = (string) $this->expression;
|
||||||
|
if (strpos($expression, '*') === false) {
|
||||||
|
return (string) $row->{$this->column} !== $expression;
|
||||||
|
} else {
|
||||||
|
$parts = array();
|
||||||
|
foreach (preg_split('/\*/', $expression) as $part) {
|
||||||
|
$parts[] = preg_quote($part);
|
||||||
|
}
|
||||||
|
return ! preg_match('/^' . implode('.*', $parts) . '$/', $row->{$this->column});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
library/Icinga/Data/Filter/FilterNotEqual.php
Normal file
13
library/Icinga/Data/Filter/FilterNotEqual.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
|
namespace Icinga\Data\Filter;
|
||||||
|
|
||||||
|
class FilterNotEqual extends FilterExpression
|
||||||
|
{
|
||||||
|
public function matches($row)
|
||||||
|
{
|
||||||
|
return (string) $row->{$this->column} !== (string) $this->expression;
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
namespace Icinga\Data\Filter;
|
namespace Icinga\Data\Filter;
|
||||||
|
|
||||||
use Exception;
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
class FilterParseException extends Exception
|
class FilterParseException extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -111,13 +111,13 @@ class FilterQueryString
|
|||||||
$extra .= "\n" . implode("\n", $this->debug);
|
$extra .= "\n" . implode("\n", $this->debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FilterParseException(sprintf(
|
throw new FilterParseException(
|
||||||
'Invalid filter "%s", unexpected %s at pos %d%s',
|
'Invalid filter "%s", unexpected %s at pos %d%s',
|
||||||
$this->string,
|
$this->string,
|
||||||
$char,
|
$char,
|
||||||
$this->pos,
|
$this->pos,
|
||||||
$extra
|
$extra
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function readFilters($nestingLevel = 0, $op = null)
|
protected function readFilters($nestingLevel = 0, $op = null)
|
||||||
|
@ -12,15 +12,25 @@ use Icinga\Data\Db\DbConnection;
|
|||||||
use Icinga\Protocol\Livestatus\Connection as LivestatusConnection;
|
use Icinga\Protocol\Livestatus\Connection as LivestatusConnection;
|
||||||
use Icinga\Protocol\Statusdat\Reader as StatusdatReader;
|
use Icinga\Protocol\Statusdat\Reader as StatusdatReader;
|
||||||
use Icinga\Protocol\Ldap\Connection as LdapConnection;
|
use Icinga\Protocol\Ldap\Connection as LdapConnection;
|
||||||
use Icinga\Protocol\File\Reader as FileReader;
|
use Icinga\Protocol\File\FileReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create resources from names or resource configuration
|
||||||
|
*/
|
||||||
class ResourceFactory implements ConfigAwareFactory
|
class ResourceFactory implements ConfigAwareFactory
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
* Resource configuration
|
||||||
|
*
|
||||||
* @var Zend_Config
|
* @var Zend_Config
|
||||||
*/
|
*/
|
||||||
private static $resources;
|
private static $resources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set resource configurations
|
||||||
|
*
|
||||||
|
* @param Zend_Config $config
|
||||||
|
*/
|
||||||
public static function setConfig($config)
|
public static function setConfig($config)
|
||||||
{
|
{
|
||||||
self::$resources = $config;
|
self::$resources = $config;
|
||||||
@ -32,14 +42,16 @@ class ResourceFactory implements ConfigAwareFactory
|
|||||||
* @param $resourceName String The resource's name
|
* @param $resourceName String The resource's name
|
||||||
*
|
*
|
||||||
* @return Zend_Config The configuration of the resource
|
* @return Zend_Config The configuration of the resource
|
||||||
* @throws \Icinga\Exception\ConfigurationError
|
*
|
||||||
|
* @throws ConfigurationError
|
||||||
*/
|
*/
|
||||||
public static function getResourceConfig($resourceName)
|
public static function getResourceConfig($resourceName)
|
||||||
{
|
{
|
||||||
self::assertResourcesExist();
|
self::assertResourcesExist();
|
||||||
if (($resourceConfig = self::$resources->get($resourceName)) === null) {
|
if (($resourceConfig = self::$resources->get($resourceName)) === null) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Cannot load resource config "' . $resourceName . '". Resource does not exist'
|
'Cannot load resource config "%s". Resource does not exist',
|
||||||
|
$resourceName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $resourceConfig;
|
return $resourceConfig;
|
||||||
@ -71,13 +83,13 @@ class ResourceFactory implements ConfigAwareFactory
|
|||||||
/**
|
/**
|
||||||
* Check if the existing resources are set. If not, throw an error.
|
* Check if the existing resources are set. If not, throw an error.
|
||||||
*
|
*
|
||||||
* @throws \Icinga\Exception\ProgrammingError
|
* @throws ProgrammingError
|
||||||
*/
|
*/
|
||||||
private static function assertResourcesExist()
|
private static function assertResourcesExist()
|
||||||
{
|
{
|
||||||
if (!isset(self::$resources)) {
|
if (!isset(self::$resources)) {
|
||||||
throw new ProgrammingError(
|
throw new ProgrammingError(
|
||||||
"The ResourceFactory must be initialised by setting a config, before it can be used"
|
'The ResourceFactory must be initialised by setting a config, before it can be used'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,7 +104,7 @@ class ResourceFactory implements ConfigAwareFactory
|
|||||||
*
|
*
|
||||||
* @return DbConnection|LdapConnection|LivestatusConnection|StatusdatReader An objects that can be used to access
|
* @return DbConnection|LdapConnection|LivestatusConnection|StatusdatReader An objects that can be used to access
|
||||||
* the given resource. The returned class depends on the configuration property 'type'.
|
* the given resource. The returned class depends on the configuration property 'type'.
|
||||||
* @throws \Icinga\Exception\ConfigurationError When an unsupported type is given
|
* @throws ConfigurationError When an unsupported type is given
|
||||||
*/
|
*/
|
||||||
public static function createResource(Zend_Config $config)
|
public static function createResource(Zend_Config $config)
|
||||||
{
|
{
|
||||||
@ -113,23 +125,22 @@ class ResourceFactory implements ConfigAwareFactory
|
|||||||
$resource = new FileReader($config);
|
$resource = new FileReader($config);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ConfigurationError('Unsupported resource type "' . $config->type . '"');
|
throw new ConfigurationError(
|
||||||
|
'Unsupported resource type "%s"',
|
||||||
|
$config->type
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return $resource;
|
return $resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function ldapAvailable()
|
/**
|
||||||
|
* Create a resource from name
|
||||||
|
*
|
||||||
|
* @param string $resourceName
|
||||||
|
* @return DbConnection|LdapConnection|LivestatusConnection|StatusdatReader
|
||||||
|
*/
|
||||||
|
public static function create($resourceName)
|
||||||
{
|
{
|
||||||
return extension_loaded('ldap');
|
return self::createResource(self::getResourceConfig($resourceName));
|
||||||
}
|
|
||||||
|
|
||||||
public static function pgsqlAvailable()
|
|
||||||
{
|
|
||||||
return extension_loaded('pgsql');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function mysqlAvailable()
|
|
||||||
{
|
|
||||||
return extension_loaded('mysql');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ use Icinga\Data\Filter\Filter;
|
|||||||
use Icinga\Web\Paginator\Adapter\QueryAdapter;
|
use Icinga\Web\Paginator\Adapter\QueryAdapter;
|
||||||
use Zend_Paginator;
|
use Zend_Paginator;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
class SimpleQuery implements QueryInterface, Queryable
|
class SimpleQuery implements QueryInterface, Queryable
|
||||||
{
|
{
|
||||||
@ -158,7 +159,7 @@ class SimpleQuery implements QueryInterface, Queryable
|
|||||||
|
|
||||||
public function setOrderColumns(array $orderColumns)
|
public function setOrderColumns(array $orderColumns)
|
||||||
{
|
{
|
||||||
throw new Exception('This function does nothing and will be removed');
|
throw new IcingaException('This function does nothing and will be removed');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,11 +4,9 @@
|
|||||||
|
|
||||||
namespace Icinga\Exception;
|
namespace Icinga\Exception;
|
||||||
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown if an error occurs during authentication
|
* Exception thrown if an error occurs during authentication
|
||||||
*/
|
*/
|
||||||
class AuthenticationException extends RuntimeException
|
class AuthenticationException extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@ namespace Icinga\Exception;
|
|||||||
* Class ConfigurationError
|
* Class ConfigurationError
|
||||||
* @package Icinga\Exception
|
* @package Icinga\Exception
|
||||||
*/
|
*/
|
||||||
class ConfigurationError extends \RuntimeException
|
class ConfigurationError extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
29
library/Icinga/Exception/IcingaException.php
Normal file
29
library/Icinga/Exception/IcingaException.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
|
namespace Icinga\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class IcingaException extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $message format string for vsprintf()
|
||||||
|
* Any futher args: args for vsprintf()
|
||||||
|
* @see vsprintf
|
||||||
|
*
|
||||||
|
* If there is at least one exception, the last one will be also used for the exception chaining.
|
||||||
|
*/
|
||||||
|
public function __construct($message = '')
|
||||||
|
{
|
||||||
|
$args = array_slice(func_get_args(), 1);
|
||||||
|
$exc = null;
|
||||||
|
foreach ($args as &$arg) {
|
||||||
|
if ($arg instanceof Exception) {
|
||||||
|
$exc = $arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent::__construct(vsprintf($message, $args), 0, $exc);
|
||||||
|
}
|
||||||
|
}
|
@ -4,12 +4,10 @@
|
|||||||
|
|
||||||
namespace Icinga\Exception;
|
namespace Icinga\Exception;
|
||||||
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class MissingParameterException
|
* Class MissingParameterException
|
||||||
* @package Icinga\Exception
|
* @package Icinga\Exception
|
||||||
*/
|
*/
|
||||||
class MissingParameterException extends RuntimeException
|
class MissingParameterException extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@ namespace Icinga\Exception;
|
|||||||
* Class NotImplementedError
|
* Class NotImplementedError
|
||||||
* @package Icinga\Exception
|
* @package Icinga\Exception
|
||||||
*/
|
*/
|
||||||
class NotImplementedError extends \Exception
|
class NotImplementedError extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
namespace Icinga\Exception;
|
namespace Icinga\Exception;
|
||||||
|
|
||||||
use RuntimeException;
|
class NotReadableError extends IcingaException
|
||||||
|
|
||||||
class NotReadableError extends RuntimeException
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
namespace Icinga\Exception;
|
namespace Icinga\Exception;
|
||||||
|
|
||||||
use RuntimeException;
|
class NotWritableError extends IcingaException
|
||||||
|
|
||||||
class NotWritableError extends RuntimeException
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@ namespace Icinga\Exception;
|
|||||||
* Class ProgrammingError
|
* Class ProgrammingError
|
||||||
* @package Icinga\Exception
|
* @package Icinga\Exception
|
||||||
*/
|
*/
|
||||||
class ProgrammingError extends \Exception
|
class ProgrammingError extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,9 @@
|
|||||||
|
|
||||||
namespace Icinga\Exception;
|
namespace Icinga\Exception;
|
||||||
|
|
||||||
use \Exception;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle problems according to file system permissions
|
* Handle problems according to file system permissions
|
||||||
*/
|
*/
|
||||||
class SystemPermissionException extends Exception
|
class SystemPermissionException extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,17 @@ class Logger
|
|||||||
/**
|
/**
|
||||||
* The log writer to use
|
* The log writer to use
|
||||||
*
|
*
|
||||||
* @var LogWriter
|
* @var \Icinga\Logger\LogWriter
|
||||||
*/
|
*/
|
||||||
protected $writer;
|
protected $writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The configured type
|
||||||
|
*
|
||||||
|
* @string Type (syslog, file)
|
||||||
|
*/
|
||||||
|
protected $type = 'none';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum severity to emit
|
* The maximum severity to emit
|
||||||
*
|
*
|
||||||
@ -52,7 +59,7 @@ class Logger
|
|||||||
$this->verbosity = $config->level;
|
$this->verbosity = $config->level;
|
||||||
|
|
||||||
if ($config->enable) {
|
if ($config->enable) {
|
||||||
$this->writer = $this->getWriter($config);
|
$this->writer = $this->createWriter($config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,16 +78,19 @@ class Logger
|
|||||||
*
|
*
|
||||||
* @param Zend_Config $config The configuration to initialize the writer with
|
* @param Zend_Config $config The configuration to initialize the writer with
|
||||||
*
|
*
|
||||||
* @return LogWriter The requested log writer
|
* @return \Icinga\Logger\LogWriter The requested log writer
|
||||||
*
|
* @throws ConfigurationError If the requested writer cannot be found
|
||||||
* @throws ConfigurationError In case the requested writer cannot be found
|
|
||||||
*/
|
*/
|
||||||
protected function getWriter(Zend_Config $config)
|
protected function createWriter(Zend_Config $config)
|
||||||
{
|
{
|
||||||
$class = 'Icinga\\Logger\\Writer\\' . ucfirst(strtolower($config->type)) . 'Writer';
|
$class = 'Icinga\\Logger\\Writer\\' . ucfirst(strtolower($config->type)) . 'Writer';
|
||||||
if (!class_exists($class)) {
|
if (!class_exists($class)) {
|
||||||
throw new ConfigurationError('Cannot find log writer of type "' . $config->type . '"');
|
throw new ConfigurationError(
|
||||||
|
'Cannot find log writer of type "%s"',
|
||||||
|
$config->type
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
$this->type = $config->type;
|
||||||
|
|
||||||
return new $class($config);
|
return new $class($config);
|
||||||
}
|
}
|
||||||
@ -191,4 +201,34 @@ class Logger
|
|||||||
static::$instance->log(static::formatMessage(func_get_args()), static::$DEBUG);
|
static::$instance->log(static::formatMessage(func_get_args()), static::$DEBUG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the log writer to use
|
||||||
|
*
|
||||||
|
* @return \Icinga\Logger\LogWriter
|
||||||
|
*/
|
||||||
|
public function getWriter()
|
||||||
|
{
|
||||||
|
return $this->writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writesToSyslog()
|
||||||
|
{
|
||||||
|
return static::$instance && static::$instance->type === 'syslog';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writesToFile()
|
||||||
|
{
|
||||||
|
return static::$instance && static::$instance->type === 'file';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this' instance
|
||||||
|
*
|
||||||
|
* @return Logger
|
||||||
|
*/
|
||||||
|
public static function getInstance()
|
||||||
|
{
|
||||||
|
return static::$instance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
namespace Icinga\Logger\Writer;
|
namespace Icinga\Logger\Writer;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
use Zend_Config;
|
use Zend_Config;
|
||||||
use Icinga\Util\File;
|
use Icinga\Util\File;
|
||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
@ -33,13 +34,20 @@ class FileWriter extends LogWriter
|
|||||||
$this->path = $config->target;
|
$this->path = $config->target;
|
||||||
|
|
||||||
if (substr($this->path, 0, 6) !== 'php://' && false === file_exists(dirname($this->path))) {
|
if (substr($this->path, 0, 6) !== 'php://' && false === file_exists(dirname($this->path))) {
|
||||||
throw new ConfigurationError('Log path "' . dirname($this->path) . '" does not exist');
|
throw new ConfigurationError(
|
||||||
|
'Log path "%s" does not exist',
|
||||||
|
dirname($this->path)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->write(''); // Avoid to handle such errors on every write access
|
$this->write(''); // Avoid to handle such errors on every write access
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new ConfigurationError('Cannot write to log file "' . $this->path . '" (' . $e->getMessage() . ')');
|
throw new ConfigurationError(
|
||||||
|
'Cannot write to log file "%s" (%s)',
|
||||||
|
$this->path,
|
||||||
|
$e->getMessage()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +69,7 @@ class FileWriter extends LogWriter
|
|||||||
*
|
*
|
||||||
* @return string The string representation of the severity
|
* @return string The string representation of the severity
|
||||||
*
|
*
|
||||||
* @throws Exception In case the given severity is unknown
|
* @throws IcingaException In case the given severity is unknown
|
||||||
*/
|
*/
|
||||||
protected function getSeverityString($severity)
|
protected function getSeverityString($severity)
|
||||||
{
|
{
|
||||||
@ -75,7 +83,10 @@ class FileWriter extends LogWriter
|
|||||||
case Logger::$DEBUG:
|
case Logger::$DEBUG:
|
||||||
return '- DEBUG -';
|
return '- DEBUG -';
|
||||||
default:
|
default:
|
||||||
throw new Exception('Unknown severity "' . $severity . '"');
|
throw new IcingaException(
|
||||||
|
'Unknown severity "%s"',
|
||||||
|
$severity
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,4 +103,12 @@ class FileWriter extends LogWriter
|
|||||||
$file->fwrite($text);
|
$file->fwrite($text);
|
||||||
$file->fflush();
|
$file->fflush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPath()
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ use Zend_Config;
|
|||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
use Icinga\Logger\LogWriter;
|
use Icinga\Logger\LogWriter;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to write messages to syslog
|
* Class to write messages to syslog
|
||||||
@ -45,7 +46,8 @@ class SyslogWriter extends LogWriter
|
|||||||
{
|
{
|
||||||
if (!array_key_exists($config->facility, $this->facilities)) {
|
if (!array_key_exists($config->facility, $this->facilities)) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Cannot create syslog writer with unknown facility "' . $config->facility . '"'
|
'Cannot create syslog writer with unknown facility "%s"',
|
||||||
|
$config->facility
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +73,10 @@ class SyslogWriter extends LogWriter
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!array_key_exists($severity, $priorities)) {
|
if (!array_key_exists($severity, $priorities)) {
|
||||||
throw new Exception('Severity "' . $severity . '" cannot be mapped to a valid syslog priority');
|
throw new IcingaException(
|
||||||
|
'Severity "%s" cannot be mapped to a valid syslog priority',
|
||||||
|
$severity
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->open();
|
$this->open();
|
||||||
|
@ -138,7 +138,10 @@ abstract class Command
|
|||||||
*/
|
*/
|
||||||
public function getHostgroupCommand($hostgroup)
|
public function getHostgroupCommand($hostgroup)
|
||||||
{
|
{
|
||||||
throw new ProgrammingError(get_class($this) . ' does not provide a hostgroup command');
|
throw new ProgrammingError(
|
||||||
|
'%s does not provide a hostgroup command',
|
||||||
|
get_class($this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,7 +153,10 @@ abstract class Command
|
|||||||
*/
|
*/
|
||||||
public function getServicegroupCommand($servicegroup)
|
public function getServicegroupCommand($servicegroup)
|
||||||
{
|
{
|
||||||
throw new ProgrammingError(get_class($this) . ' does not provide a servicegroup command');
|
throw new ProgrammingError(
|
||||||
|
'%s does not provide a servicegroup command',
|
||||||
|
get_class($this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,6 +169,9 @@ abstract class Command
|
|||||||
*/
|
*/
|
||||||
public function getGlobalCommand($instance = null)
|
public function getGlobalCommand($instance = null)
|
||||||
{
|
{
|
||||||
throw new ProgrammingError(getclass($this) . ' does not provide a global command');
|
throw new ProgrammingError(
|
||||||
|
'%s does not provide a global command',
|
||||||
|
getclass($this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,9 @@ class LocalPipe implements Transport
|
|||||||
$file->fflush();
|
$file->fflush();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
sprintf(
|
|
||||||
'Could not open icinga command pipe at "%s" (%s)',
|
'Could not open icinga command pipe at "%s" (%s)',
|
||||||
$this->path,
|
$this->path,
|
||||||
$e->getMessage()
|
$e->getMessage()
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Protocol\Commandpipe\Transport;
|
namespace Icinga\Protocol\Commandpipe\Transport;
|
||||||
|
|
||||||
use \Zend_Config;
|
use Zend_Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for Transport classes handling the concrete access to the command pipe
|
* Interface for Transport classes handling the concrete access to the command pipe
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace Icinga\Protocol\File;
|
namespace Icinga\Protocol\File;
|
||||||
|
|
||||||
use RuntimeException;
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown if a file reader specific error occurs
|
* Exception thrown if a file reader specific error occurs
|
||||||
*/
|
*/
|
||||||
class FileReaderException extends RuntimeException {}
|
class FileReaderException extends IcingaException {}
|
||||||
|
82
library/Icinga/Protocol/File/FileIterator.php
Normal file
82
library/Icinga/Protocol/File/FileIterator.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
// {{{ICINGA_LICENSE_HEADER}}}
|
||||||
|
|
||||||
|
namespace Icinga\Protocol\File;
|
||||||
|
|
||||||
|
use FilterIterator;
|
||||||
|
use Icinga\Util\File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class FileIterator
|
||||||
|
*
|
||||||
|
* Iterate over a file, yielding only fields of non-empty lines which match a PCRE expression
|
||||||
|
*/
|
||||||
|
class FileIterator extends FilterIterator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A PCRE string with the fields to extract from the file's lines as named subpatterns
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $fields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An associative array of the current line's fields ($field => $value)
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $currentData;
|
||||||
|
|
||||||
|
public function __construct($filename, $fields)
|
||||||
|
{
|
||||||
|
$this->fields = $fields;
|
||||||
|
$f = new File($filename);
|
||||||
|
$f->setFlags(
|
||||||
|
File::DROP_NEW_LINE |
|
||||||
|
File::READ_AHEAD |
|
||||||
|
File::SKIP_EMPTY
|
||||||
|
);
|
||||||
|
parent::__construct($f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current data
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
return $this->currentData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept lines matching the given PCRE pattern
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*
|
||||||
|
* @throws FileReaderException If PHP failed parsing the PCRE pattern
|
||||||
|
*/
|
||||||
|
public function accept()
|
||||||
|
{
|
||||||
|
$data = array();
|
||||||
|
$matched = preg_match(
|
||||||
|
$this->fields,
|
||||||
|
$this->getInnerIterator()->current(),
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($matched === false) {
|
||||||
|
throw new FileReaderException('Failed parsing regular expression!');
|
||||||
|
} else if ($matched === 1) {
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
if (is_int($key)) {
|
||||||
|
unset($data[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->currentData = $data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -8,13 +8,13 @@ use Icinga\Data\SimpleQuery;
|
|||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Query
|
* Class FileQuery
|
||||||
*
|
*
|
||||||
* Query for Datasource Icinga\Protocol\File\Reader
|
* Query for Datasource Icinga\Protocol\File\FileReader
|
||||||
*
|
*
|
||||||
* @package Icinga\Protocol\File
|
* @package Icinga\Protocol\File
|
||||||
*/
|
*/
|
||||||
class Query extends SimpleQuery
|
class FileQuery extends SimpleQuery
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Sort direction
|
* Sort direction
|
||||||
@ -41,7 +41,7 @@ class Query extends SimpleQuery
|
|||||||
*
|
*
|
||||||
* @param string $dir Sort direction, 'ASC' or 'DESC' (default)
|
* @param string $dir Sort direction, 'ASC' or 'DESC' (default)
|
||||||
*
|
*
|
||||||
* @return Query
|
* @return FileQuery
|
||||||
*/
|
*/
|
||||||
public function order($field, $direction = null)
|
public function order($field, $direction = null)
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@ class Query extends SimpleQuery
|
|||||||
*
|
*
|
||||||
* @param string $expression the filter expression to be applied
|
* @param string $expression the filter expression to be applied
|
||||||
*
|
*
|
||||||
* @return Query
|
* @return FileQuery
|
||||||
*/
|
*/
|
||||||
public function andWhere($expression)
|
public function andWhere($expression)
|
||||||
{
|
{
|
@ -4,16 +4,15 @@
|
|||||||
|
|
||||||
namespace Icinga\Protocol\File;
|
namespace Icinga\Protocol\File;
|
||||||
|
|
||||||
use FilterIterator;
|
use Icinga\Data\Selectable;
|
||||||
use Iterator;
|
use Countable;
|
||||||
|
use Icinga\Util\Enumerate;
|
||||||
use Zend_Config;
|
use Zend_Config;
|
||||||
use Icinga\Protocol\File\FileReaderException;
|
|
||||||
use Icinga\Util\File;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read file line by line
|
* Read file line by line
|
||||||
*/
|
*/
|
||||||
class Reader extends FilterIterator
|
class FileReader implements Selectable, Countable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* A PCRE string with the fields to extract from the file's lines as named subpatterns
|
* A PCRE string with the fields to extract from the file's lines as named subpatterns
|
||||||
@ -23,11 +22,11 @@ class Reader extends FilterIterator
|
|||||||
protected $fields;
|
protected $fields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An associative array of the current line's fields ($field => $value)
|
* Name of the target file
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $currentData;
|
protected $filename;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new reader
|
* Create a new reader
|
||||||
@ -39,67 +38,34 @@ class Reader extends FilterIterator
|
|||||||
public function __construct(Zend_Config $config)
|
public function __construct(Zend_Config $config)
|
||||||
{
|
{
|
||||||
foreach (array('filename', 'fields') as $key) {
|
foreach (array('filename', 'fields') as $key) {
|
||||||
if (! isset($config->{$key})) {
|
if (isset($config->{$key})) {
|
||||||
throw new FileReaderException('The directive `' . $key . '\' is required');
|
$this->{$key} = $config->{$key};
|
||||||
|
} else {
|
||||||
|
throw new FileReaderException('The directive `%s\' is required', $key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->fields = $config->fields;
|
|
||||||
$f = new File($config->filename);
|
|
||||||
$f->setFlags(
|
|
||||||
File::DROP_NEW_LINE |
|
|
||||||
File::READ_AHEAD |
|
|
||||||
File::SKIP_EMPTY
|
|
||||||
);
|
|
||||||
parent::__construct($f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the current data
|
* Instantiate a FileIterator object with the target file
|
||||||
*
|
*
|
||||||
* @return array
|
* @return FileIterator
|
||||||
*/
|
*/
|
||||||
public function current()
|
public function iterate()
|
||||||
{
|
{
|
||||||
return $this->currentData;
|
return new Enumerate(
|
||||||
}
|
new FileIterator($this->filename, $this->fields)
|
||||||
|
|
||||||
/**
|
|
||||||
* Accept lines matching the given PCRE pattern
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @throws FileReaderException If PHP failed parsing the PCRE pattern
|
|
||||||
*/
|
|
||||||
public function accept()
|
|
||||||
{
|
|
||||||
$data = array();
|
|
||||||
$matched = @preg_match(
|
|
||||||
$this->fields,
|
|
||||||
$this->getInnerIterator()->current(),
|
|
||||||
$data
|
|
||||||
);
|
);
|
||||||
if ($matched === false) {
|
|
||||||
throw new FileReaderException('Failed parsing regular expression!');
|
|
||||||
} else if ($matched === 1) {
|
|
||||||
foreach ($data as $key) {
|
|
||||||
if (is_int($key)) {
|
|
||||||
unset($data[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->currentData = $data;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate a Query object
|
* Instantiate a FileQuery object
|
||||||
*
|
*
|
||||||
* @return Query
|
* @return FileQuery
|
||||||
*/
|
*/
|
||||||
public function select()
|
public function select()
|
||||||
{
|
{
|
||||||
return new Query($this);
|
return new FileQuery($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,17 +75,17 @@ class Reader extends FilterIterator
|
|||||||
*/
|
*/
|
||||||
public function count()
|
public function count()
|
||||||
{
|
{
|
||||||
return iterator_count($this);
|
return iterator_count($this->iterate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch result as an array of objects
|
* Fetch result as an array of objects
|
||||||
*
|
*
|
||||||
* @param Query $query
|
* @param FileQuery $query
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function fetchAll(Query $query)
|
public function fetchAll(FileQuery $query)
|
||||||
{
|
{
|
||||||
$all = array();
|
$all = array();
|
||||||
foreach ($this->fetchPairs($query) as $index => $value) {
|
foreach ($this->fetchPairs($query) as $index => $value) {
|
||||||
@ -131,32 +97,32 @@ class Reader extends FilterIterator
|
|||||||
/**
|
/**
|
||||||
* Fetch result as a key/value pair array
|
* Fetch result as a key/value pair array
|
||||||
*
|
*
|
||||||
* @param Query $query
|
* @param FileQuery $query
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function fetchPairs(Query $query)
|
public function fetchPairs(FileQuery $query)
|
||||||
{
|
{
|
||||||
$skipLines = $query->getOffset();
|
$skip = $query->getOffset();
|
||||||
$readLines = $query->getLimit();
|
$read = $query->getLimit();
|
||||||
if ($skipLines === null) {
|
if ($skip === null) {
|
||||||
$skipLines = 0;
|
$skip = 0;
|
||||||
}
|
}
|
||||||
$lines = array();
|
$lines = array();
|
||||||
if ($query->sortDesc()) {
|
if ($query->sortDesc()) {
|
||||||
$count = $this->count($query);
|
$count = $this->count($query);
|
||||||
if ($count <= $skipLines) {
|
if ($count <= $skip) {
|
||||||
return $lines;
|
return $lines;
|
||||||
} else if ($count < ($skipLines + $readLines)) {
|
} else if ($count < ($skip + $read)) {
|
||||||
$readLines = $count - $skipLines;
|
$read = $count - $skip;
|
||||||
$skipLines = 0;
|
$skip = 0;
|
||||||
} else {
|
} else {
|
||||||
$skipLines = $count - ($skipLines + $readLines);
|
$skip = $count - ($skip + $read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($this as $index => $line) {
|
foreach ($this->iterate() as $index => $line) {
|
||||||
if ($index >= $skipLines) {
|
if ($index >= $skip) {
|
||||||
if ($index >= $skipLines + $readLines) {
|
if ($index >= $skip + $read) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$lines[] = $line;
|
$lines[] = $line;
|
||||||
@ -171,11 +137,11 @@ class Reader extends FilterIterator
|
|||||||
/**
|
/**
|
||||||
* Fetch first result row
|
* Fetch first result row
|
||||||
*
|
*
|
||||||
* @param Query $query
|
* @param FileQuery $query
|
||||||
*
|
*
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public function fetchRow(Query $query)
|
public function fetchRow(FileQuery $query)
|
||||||
{
|
{
|
||||||
$all = $this->fetchAll($query);
|
$all = $this->fetchAll($query);
|
||||||
if (isset($all[0])) {
|
if (isset($all[0])) {
|
||||||
@ -187,11 +153,11 @@ class Reader extends FilterIterator
|
|||||||
/**
|
/**
|
||||||
* Fetch first result column
|
* Fetch first result column
|
||||||
*
|
*
|
||||||
* @param Query $query
|
* @param FileQuery $query
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function fetchColumn(Query $query)
|
public function fetchColumn(FileQuery $query)
|
||||||
{
|
{
|
||||||
$column = array();
|
$column = array();
|
||||||
foreach ($this->fetchPairs($query) as $pair) {
|
foreach ($this->fetchPairs($query) as $pair) {
|
||||||
@ -206,11 +172,11 @@ class Reader extends FilterIterator
|
|||||||
/**
|
/**
|
||||||
* Fetch first column value from first result row
|
* Fetch first column value from first result row
|
||||||
*
|
*
|
||||||
* @param Query $query
|
* @param FileQuery $query
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function fetchOne(Query $query)
|
public function fetchOne(FileQuery $query)
|
||||||
{
|
{
|
||||||
$pairs = $this->fetchPairs($query);
|
$pairs = $this->fetchPairs($query);
|
||||||
if (isset($pairs[0])) {
|
if (isset($pairs[0])) {
|
@ -8,7 +8,7 @@ use Icinga\Protocol\Ldap\Exception as LdapException;
|
|||||||
use Icinga\Application\Platform;
|
use Icinga\Application\Platform;
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Logger\Logger;
|
use Icinga\Logger\Logger;
|
||||||
use \Zend_Config;
|
use Zend_Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backend class managing all the LDAP stuff for you.
|
* Backend class managing all the LDAP stuff for you.
|
||||||
@ -307,7 +307,7 @@ class Connection
|
|||||||
$results = @ldap_search(
|
$results = @ldap_search(
|
||||||
$this->ds,
|
$this->ds,
|
||||||
$base,
|
$base,
|
||||||
(string) $query,
|
$query->create(),
|
||||||
$fields,
|
$fields,
|
||||||
0, // Attributes and values
|
0, // Attributes and values
|
||||||
0 // No limit - at least where possible
|
0 // No limit - at least where possible
|
||||||
@ -619,7 +619,7 @@ class Connection
|
|||||||
$result = @ldap_read(
|
$result = @ldap_read(
|
||||||
$ds,
|
$ds,
|
||||||
'',
|
'',
|
||||||
(string) $query,
|
$query->create(),
|
||||||
$query->listFields()
|
$query->listFields()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -83,11 +83,9 @@ class Query
|
|||||||
{
|
{
|
||||||
if (! preg_match('~^\d+~', $count . $offset)) {
|
if (! preg_match('~^\d+~', $count . $offset)) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
sprintf(
|
|
||||||
'Got invalid limit: %s, %s',
|
'Got invalid limit: %s, %s',
|
||||||
$count,
|
$count,
|
||||||
$offset
|
$offset
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->limit_count = (int) $count;
|
$this->limit_count = (int) $count;
|
||||||
@ -302,21 +300,11 @@ class Query
|
|||||||
*
|
*
|
||||||
* @string
|
* @string
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function create()
|
||||||
{
|
|
||||||
return $this->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the LDAP filter that will be applied
|
|
||||||
*
|
|
||||||
* @string
|
|
||||||
*/
|
|
||||||
protected function render()
|
|
||||||
{
|
{
|
||||||
$parts = array();
|
$parts = array();
|
||||||
if (! isset($this->filters['objectClass']) || $this->filters['objectClass'] === null) {
|
if (! isset($this->filters['objectClass']) || $this->filters['objectClass'] === null) {
|
||||||
// throw new Exception('Object class is mandatory');
|
throw new Exception('Object class is mandatory');
|
||||||
}
|
}
|
||||||
foreach ($this->filters as $key => $value) {
|
foreach ($this->filters as $key => $value) {
|
||||||
$parts[] = sprintf(
|
$parts[] = sprintf(
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
namespace Icinga\Protocol\Ldap;
|
namespace Icinga\Protocol\Ldap;
|
||||||
|
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a special node object, representing your connections root node
|
* This class is a special node object, representing your connections root node
|
||||||
*
|
*
|
||||||
@ -95,16 +97,14 @@ class Root
|
|||||||
/**
|
/**
|
||||||
* @param $rdn
|
* @param $rdn
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws Exception
|
* @throws IcingaException
|
||||||
*/
|
*/
|
||||||
public function getChildByRDN($rdn)
|
public function getChildByRDN($rdn)
|
||||||
{
|
{
|
||||||
if (!$this->hasChildRDN($rdn)) {
|
if (!$this->hasChildRDN($rdn)) {
|
||||||
throw new Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'The child RDN "%s" is not available',
|
'The child RDN "%s" is not available',
|
||||||
$rdn
|
$rdn
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $this->children[strtolower($rdn)];
|
return $this->children[strtolower($rdn)];
|
||||||
@ -154,28 +154,24 @@ class Root
|
|||||||
/**
|
/**
|
||||||
* @param $dn
|
* @param $dn
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws Exception
|
* @throws IcingaException
|
||||||
*/
|
*/
|
||||||
protected function assertSubDN($dn)
|
protected function assertSubDN($dn)
|
||||||
{
|
{
|
||||||
$mydn = $this->getDN();
|
$mydn = $this->getDN();
|
||||||
$end = substr($dn, -1 * strlen($mydn));
|
$end = substr($dn, -1 * strlen($mydn));
|
||||||
if (strtolower($end) !== strtolower($mydn)) {
|
if (strtolower($end) !== strtolower($mydn)) {
|
||||||
throw new Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'"%s" is not a child of "%s"',
|
'"%s" is not a child of "%s"',
|
||||||
$dn,
|
$dn,
|
||||||
$mydn
|
$mydn
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (strlen($dn) === strlen($mydn)) {
|
if (strlen($dn) === strlen($mydn)) {
|
||||||
throw new Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'"%s" is not a child of "%s", they are equal',
|
'"%s" is not a child of "%s", they are equal',
|
||||||
$dn,
|
$dn,
|
||||||
$mydn
|
$mydn
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -6,6 +6,7 @@ namespace Icinga\Protocol\Livestatus;
|
|||||||
|
|
||||||
use Icinga\Application\Benchmark;
|
use Icinga\Application\Benchmark;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backend class managing handling MKI Livestatus connections
|
* Backend class managing handling MKI Livestatus connections
|
||||||
@ -73,22 +74,18 @@ class Connection
|
|||||||
$this->assertPhpExtensionLoaded('sockets');
|
$this->assertPhpExtensionLoaded('sockets');
|
||||||
if ($socket[0] === '/') {
|
if ($socket[0] === '/') {
|
||||||
if (! is_writable($socket)) {
|
if (! is_writable($socket)) {
|
||||||
throw new \Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'Cannot write to livestatus socket "%s"',
|
'Cannot write to livestatus socket "%s"',
|
||||||
$socket
|
$socket
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->socket_type = self::TYPE_UNIX;
|
$this->socket_type = self::TYPE_UNIX;
|
||||||
$this->socket_path = $socket;
|
$this->socket_path = $socket;
|
||||||
} else {
|
} else {
|
||||||
if (! preg_match('~^tcp://([^:]+):(\d+)~', $socket, $m)) {
|
if (! preg_match('~^tcp://([^:]+):(\d+)~', $socket, $m)) {
|
||||||
throw new \Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'Invalid TCP socket syntax: "%s"',
|
'Invalid TCP socket syntax: "%s"',
|
||||||
$socket
|
$socket
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: Better syntax checks
|
// TODO: Better syntax checks
|
||||||
@ -156,17 +153,15 @@ class Connection
|
|||||||
$length = (int) trim(substr($header, 4));
|
$length = (int) trim(substr($header, 4));
|
||||||
$body = $this->readFromSocket($length);
|
$body = $this->readFromSocket($length);
|
||||||
if ($status !== 200) {
|
if ($status !== 200) {
|
||||||
throw new Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'Problem while reading %d bytes from livestatus: %s',
|
'Problem while reading %d bytes from livestatus: %s',
|
||||||
$length,
|
$length,
|
||||||
$body
|
$body
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$result = json_decode($body);
|
$result = json_decode($body);
|
||||||
if ($result === null) {
|
if ($result === null) {
|
||||||
throw new Exception('Got invalid response body from livestatus');
|
throw new IcingaException('Got invalid response body from livestatus');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@ -180,11 +175,9 @@ class Connection
|
|||||||
while ($offset < $length) {
|
while ($offset < $length) {
|
||||||
$data = socket_read($this->connection, $length - $offset);
|
$data = socket_read($this->connection, $length - $offset);
|
||||||
if ($data === false) {
|
if ($data === false) {
|
||||||
throw new Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'Failed to read from livestatus socket: %s',
|
'Failed to read from livestatus socket: %s',
|
||||||
socket_strerror(socket_last_error($this->connection))
|
socket_strerror(socket_last_error($this->connection))
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$size = strlen($data);
|
$size = strlen($data);
|
||||||
@ -196,12 +189,10 @@ class Connection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($offset !== $length) {
|
if ($offset !== $length) {
|
||||||
throw new \Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'Got only %d instead of %d bytes from livestatus socket',
|
'Got only %d instead of %d bytes from livestatus socket',
|
||||||
$offset,
|
$offset,
|
||||||
$length
|
$length
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +203,7 @@ class Connection
|
|||||||
{
|
{
|
||||||
$res = socket_write($this->connection, $data);
|
$res = socket_write($this->connection, $data);
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
throw new \Exception('Writing to livestatus socket failed');
|
throw new IcingaException('Writing to livestatus socket failed');
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -220,11 +211,9 @@ class Connection
|
|||||||
protected function assertPhpExtensionLoaded($name)
|
protected function assertPhpExtensionLoaded($name)
|
||||||
{
|
{
|
||||||
if (! extension_loaded($name)) {
|
if (! extension_loaded($name)) {
|
||||||
throw new \Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'The extension "%s" is not loaded',
|
'The extension "%s" is not loaded',
|
||||||
$name
|
$name
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,13 +239,11 @@ class Connection
|
|||||||
|
|
||||||
$this->connection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
$this->connection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||||
if (! @socket_connect($this->connection, $this->socket_host, $this->socket_port)) {
|
if (! @socket_connect($this->connection, $this->socket_host, $this->socket_port)) {
|
||||||
throw new \Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'Cannot connect to livestatus TCP socket "%s:%d": %s',
|
'Cannot connect to livestatus TCP socket "%s:%d": %s',
|
||||||
$this->socket_host,
|
$this->socket_host,
|
||||||
$this->socket_port,
|
$this->socket_port,
|
||||||
socket_strerror(socket_last_error($this->connection))
|
socket_strerror(socket_last_error($this->connection))
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
socket_set_option($this->connection, SOL_TCP, TCP_NODELAY, 1);
|
socket_set_option($this->connection, SOL_TCP, TCP_NODELAY, 1);
|
||||||
@ -266,11 +253,9 @@ class Connection
|
|||||||
{
|
{
|
||||||
$this->connection = socket_create(AF_UNIX, SOCK_STREAM, 0);
|
$this->connection = socket_create(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (! socket_connect($this->connection, $this->socket_path)) {
|
if (! socket_connect($this->connection, $this->socket_path)) {
|
||||||
throw new \Exception(
|
throw new IcingaException(
|
||||||
sprintf(
|
|
||||||
'Cannot connect to livestatus local socket "%s"',
|
'Cannot connect to livestatus local socket "%s"',
|
||||||
$this->socket_path
|
$this->socket_path
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user