Merge branch 'master' into feature/translation-plural-8092
This commit is contained in:
commit
973a56c984
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
icingaweb2::config: /etc/icingaweb
|
||||
icingaweb2::log: /var/log/icingaweb/icingaweb.log
|
||||
icingaweb2::web_path: icingaweb
|
||||
icingaweb2::db_user: icingaweb
|
||||
icingaweb2::db_pass: icingaweb
|
||||
icingaweb2::db_name: icingaweb
|
||||
icingaweb2::config: /etc/icingaweb2
|
||||
icingaweb2::log: /var/log/icingaweb2/icingaweb2.log
|
||||
icingaweb2::web_path: icingaweb2
|
||||
icingaweb2::db_user: icingaweb2
|
||||
icingaweb2::db_pass: icingaweb2
|
||||
icingaweb2::db_name: icingaweb2
|
||||
|
|
|
@ -12,4 +12,6 @@ node default {
|
|||
file { '/etc/profile.d/env.sh':
|
||||
source => 'puppet:////vagrant/.puppet/files/etc/profile.d/env.sh'
|
||||
}
|
||||
@user { vagrant: ensure => present }
|
||||
User <| title == vagrant |> { groups +> icingaweb }
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# TODO(el): This module is not reuseable because it relies on vagrant paths
|
||||
class icingacli {
|
||||
file { '/usr/local/bin/icingacli':
|
||||
ensure => link,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# vi: set ft=ruby :
|
||||
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
VAGRANT_REQUIRED_VERSION = "1.2.0"
|
||||
VAGRANT_REQUIRED_VERSION = "1.5.0"
|
||||
|
||||
# Require 1.2.x at least
|
||||
if ! defined? Vagrant.require_version
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
|
||||
# namespace Icinga\Application\Controllers;
|
||||
|
||||
use Icinga\Authentication\Backend\AutoLoginBackend;
|
||||
use Icinga\Web\Controller\ActionController;
|
||||
use Icinga\Forms\Authentication\LoginForm;
|
||||
use Icinga\Authentication\AuthChain;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Authentication\AuthChain;
|
||||
use Icinga\Authentication\Backend\AutoLoginBackend;
|
||||
use Icinga\Exception\AuthenticationException;
|
||||
use Icinga\Exception\NotReadableError;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\NotReadableError;
|
||||
use Icinga\Forms\Authentication\LoginForm;
|
||||
use Icinga\User;
|
||||
use Icinga\Web\Controller\ActionController;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
/**
|
||||
|
@ -33,7 +34,8 @@ class AuthenticationController extends ActionController
|
|||
*/
|
||||
public function loginAction()
|
||||
{
|
||||
if (@file_exists(Config::resolvePath('setup.token')) && !@file_exists(Config::resolvePath('config.ini'))) {
|
||||
$icinga = Icinga::app();
|
||||
if ($icinga->setupTokenExists() && $icinga->requiresSetup()) {
|
||||
$this->redirectNow(Url::fromPath('setup'));
|
||||
}
|
||||
|
||||
|
@ -139,7 +141,7 @@ class AuthenticationController extends ActionController
|
|||
$this->view->errorInfo = $e->getMessage();
|
||||
}
|
||||
|
||||
$this->view->configMissing = is_dir(Config::$configDir) === false;
|
||||
$this->view->requiresSetup = Icinga::app()->requiresSetup();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -53,8 +53,10 @@ class AutologinBackendForm extends Form
|
|||
'strip_username_regexp',
|
||||
array(
|
||||
'label' => t('Filter Pattern'),
|
||||
'description' => t('The regular expression to use to strip specific parts off from usernames. Leave empty if you do not want to strip off anything'),
|
||||
'value' => '/\@[^$]+$/',
|
||||
'description' => t(
|
||||
'The regular expression to use to strip specific parts off from usernames.'
|
||||
. ' Leave empty if you do not want to strip off anything'
|
||||
),
|
||||
'validators' => array(
|
||||
new Zend_Validate_Callback(function ($value) {
|
||||
return @preg_match($value, '') !== false;
|
||||
|
|
|
@ -67,7 +67,7 @@ class LoggingConfigForm extends Form
|
|||
'required' => true,
|
||||
'label' => t('Application Prefix'),
|
||||
'description' => t('The name of the application by which to prefix syslog messages.'),
|
||||
'value' => 'icingaweb',
|
||||
'value' => 'icingaweb2',
|
||||
'validators' => array(
|
||||
array(
|
||||
'Regex',
|
||||
|
@ -106,7 +106,7 @@ class LoggingConfigForm extends Form
|
|||
'required' => true,
|
||||
'label' => t('File path'),
|
||||
'description' => t('The full path to the log file to write messages to.'),
|
||||
'value' => $this->getDefaultLogDir(),
|
||||
'value' => '/var/log/icingaweb2/icingaweb2.log',
|
||||
'validators' => array(new WritablePathValidator())
|
||||
)
|
||||
);
|
||||
|
@ -114,14 +114,4 @@ class LoggingConfigForm extends Form
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default logging directory for type 'file'
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultLogDir()
|
||||
{
|
||||
return realpath(Icinga::app()->getApplicationDir('../var/log/icingaweb.log'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ class LivestatusResourceForm extends Form
|
|||
'required' => true,
|
||||
'label' => t('Socket'),
|
||||
'description' => t('The path to your livestatus socket used for querying monitoring data'),
|
||||
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/rw/livestatus')
|
||||
'value' => '/var/run/icinga2/cmd/livestatus'
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Icinga\Forms\Security;
|
|||
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use Zend_Form_Element;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Util\String;
|
||||
|
@ -18,14 +19,14 @@ class RoleForm extends ConfigForm
|
|||
/**
|
||||
* Provided permissions by currently loaded modules
|
||||
*
|
||||
* @var array
|
||||
* @type array
|
||||
*/
|
||||
protected $providedPermissions = array();
|
||||
protected $providedPermissions = array('*' => '*');
|
||||
|
||||
/**
|
||||
* Provided restrictions by currently loaded modules
|
||||
*
|
||||
* @var array
|
||||
* @type array
|
||||
*/
|
||||
protected $providedRestrictions = array();
|
||||
|
||||
|
@ -35,14 +36,26 @@ class RoleForm extends ConfigForm
|
|||
*/
|
||||
public function init()
|
||||
{
|
||||
$helper = new Zend_Form_Element('bogus');
|
||||
foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $module) {
|
||||
foreach ($module->getProvidedPermissions() as $permission) {
|
||||
/** @var object $permission */
|
||||
/** @type object $permission */
|
||||
$this->providedPermissions[$permission->name] = $permission->name . ': ' . $permission->description;
|
||||
}
|
||||
foreach ($module->getProvidedRestrictions() as $restriction) {
|
||||
/** @var object $restriction */
|
||||
$this->providedRestrictions[$restriction->name] = $restriction->description;
|
||||
/** @type object $restriction */
|
||||
$name = $helper->filterName($restriction->name); // Zend only permits alphanumerics, the underscore,
|
||||
// the circumflex and any ASCII character in range
|
||||
// \x7f to \xff (127 to 255)
|
||||
while (isset($this->providedRestrictions[$name])) {
|
||||
// Because Zend_Form_Element::filterName() replaces any not permitted character with the empty
|
||||
// string we may have duplicate names, e.g. 're/striction' and 'restriction'
|
||||
$name .= '_';
|
||||
}
|
||||
$this->providedRestrictions[$name] = array(
|
||||
'description' => $restriction->description,
|
||||
'name' => $restriction->name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,13 +103,13 @@ class RoleForm extends ConfigForm
|
|||
)
|
||||
)
|
||||
));
|
||||
foreach ($this->providedRestrictions as $name => $description) {
|
||||
foreach ($this->providedRestrictions as $name => $spec) {
|
||||
$this->addElement(
|
||||
'text',
|
||||
$name,
|
||||
array(
|
||||
'label' => $name,
|
||||
'description' => $description
|
||||
'label' => $spec['name'],
|
||||
'description' => $spec['description']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -129,6 +142,15 @@ class RoleForm extends ConfigForm
|
|||
? String::trimSplit($role['permissions'])
|
||||
: null;
|
||||
$role['name'] = $name;
|
||||
$restrictions = array();
|
||||
foreach ($this->providedRestrictions as $name => $spec) {
|
||||
if (isset($role[$spec['name']])) {
|
||||
// Translate restriction names to filtered element names
|
||||
$restrictions[$name] = $role[$spec['name']];
|
||||
unset($role[$spec['name']]);
|
||||
}
|
||||
}
|
||||
$role = array_merge($role, $restrictions);
|
||||
$this->populate($role);
|
||||
return $this;
|
||||
}
|
||||
|
@ -230,6 +252,15 @@ class RoleForm extends ConfigForm
|
|||
if (isset($values['permissions'])) {
|
||||
$values['permissions'] = implode(', ', $values['permissions']);
|
||||
}
|
||||
$restrictions = array();
|
||||
foreach ($this->providedRestrictions as $name => $spec) {
|
||||
if (isset($values[$name])) {
|
||||
// Translate filtered element names to restriction names
|
||||
$restrictions[$spec['name']] = $values[$name];
|
||||
unset($values[$name]);
|
||||
}
|
||||
}
|
||||
$values = array_merge($values, $restrictions);
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
<?php endif ?>
|
||||
<?= $this->form ?>
|
||||
<div class="footer">Icinga Web 2 © 2013-2014<br><a href="https://www.icinga.org">The Icinga Project</a></div>
|
||||
<?php if ($configMissing): ?>
|
||||
<?php if ($requiresSetup): ?>
|
||||
<div class="config-note"><?= sprintf(
|
||||
t(
|
||||
'You seem not to have Icinga Web 2 configured yet so it\'s not possible to log in without any defined '
|
||||
'It appears that you did not configure Icinga Web 2 yet so it\'s not possible to log in without any defined '
|
||||
. 'authentication method. Please define a authentication method by following the instructions in the'
|
||||
. ' %1$sdocumentation%3$s or by using our %2$sweb-based setup-wizard%3$s.'
|
||||
),
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<td>
|
||||
<?php
|
||||
// TODO(el): $role->without(...) or $role->shift(...) would be nice!
|
||||
$restrictions = $role;
|
||||
$restrictions = clone $role;
|
||||
unset($restrictions['users']);
|
||||
unset($restrictions['groups']);
|
||||
unset($restrictions['permissions']);
|
||||
|
|
|
@ -2,21 +2,23 @@
|
|||
|
||||
**Choosing the Authentication Method**
|
||||
|
||||
With Icinga Web 2 you can authenticate against Active Directory, LDAP, a MySQL or PostgreSQL database or delegate
|
||||
authentication to the web server. Authentication methods can be chained to set up fallback authentication methods
|
||||
With Icinga Web 2 you can authenticate against Active Directory, LDAP, a MySQL or a PostgreSQL database or delegate
|
||||
authentication to the web server.
|
||||
|
||||
Authentication methods can be chained to set up fallback authentication methods
|
||||
or if users are spread over multiple places.
|
||||
|
||||
## Configuration
|
||||
## <a id="authentication-configuration"></a> Configuration
|
||||
|
||||
Authentication methods are configured in the INI file **config/authentication.ini**.
|
||||
|
||||
Each section in the authentication configuration represents a single authentication method.
|
||||
|
||||
The order of entries in the authentication configuration determines the order of the authentication methods.
|
||||
If the current authentication method errors or the current authentication method does not know the account being
|
||||
If the current authentication method errors or if the current authentication method does not know the account being
|
||||
authenticated, the next authentication method will be used.
|
||||
|
||||
## External Authentication
|
||||
### <a id="authentication-configuration-external-authentication"></a> External Authentication
|
||||
|
||||
For delegating authentication to the web server simply add `autologin` to your authentication configuration:
|
||||
|
||||
|
@ -27,13 +29,13 @@ backend = autologin
|
|||
|
||||
If your web server is not configured for authentication though the `autologin` section has no effect.
|
||||
|
||||
## Active Directory or LDAP Authentication
|
||||
### <a id="authentication-configuration-ad-or-ldap-authentication"></a> Active Directory or LDAP Authentication
|
||||
|
||||
If you want to authenticate against Active Directory or LDAP, you have to define a
|
||||
[LDAP resource](#resources-configuration-ldap) first which will be referenced as data source for the Active Directory
|
||||
[LDAP resource](#resources-configuration-ldap) which will be referenced as data source for the Active Directory
|
||||
or LDAP configuration method.
|
||||
|
||||
### LDAP
|
||||
#### <a id="authentication-configuration-ldap-authentication"></a> LDAP
|
||||
|
||||
Directive | Description
|
||||
------------------------|------------
|
||||
|
@ -52,7 +54,7 @@ user_class = inetOrgPerson
|
|||
user_name_attribute = uid
|
||||
```
|
||||
|
||||
### Active Directory
|
||||
#### <a id="authentication-configuration-ad-authentication"></a> Active Directory
|
||||
|
||||
Directive | Description
|
||||
------------------------|------------
|
||||
|
@ -67,10 +69,10 @@ backend = ad
|
|||
resource = my_ad
|
||||
```
|
||||
|
||||
## Database Authentication
|
||||
### <a id="authentication-configuration-db-authentication"></a> Database Authentication
|
||||
|
||||
If you want to authenticate against a MySQL or PostgreSQL database, you have to define a
|
||||
[database resource](#resources-configuration-database) first which will be referenced as data source for the database
|
||||
If you want to authenticate against a MySQL or a PostgreSQL database, you have to define a
|
||||
[database resource](#resources-configuration-database) which will be referenced as data source for the database
|
||||
authentication method.
|
||||
|
||||
Directive | Description
|
||||
|
@ -83,13 +85,31 @@ Directive | Description
|
|||
```
|
||||
[auth_ad]
|
||||
backend = ad
|
||||
resource = my_db
|
||||
resource = icingaweb-mysql
|
||||
```
|
||||
|
||||
#### <a id="authentication-configuration-db-setup"></a> Database Setup
|
||||
|
||||
For authenticating against a database, you have to import one of the following database schemas:
|
||||
|
||||
* **etc/schema/preferences.mysql.sql** (for **MySQL** database)
|
||||
* **etc/schema/preferences.pgsql.sql** (for **PostgreSQL** databases)
|
||||
|
||||
After that you have to define the [database resource](#resources-configuration-database).
|
||||
|
||||
**Manually Creating Users**
|
||||
|
||||
Icinga Web 2 uses the MD5 based BSD password algorithm. For generating a password hash, please use the following
|
||||
command:
|
||||
|
||||
````
|
||||
openssl passwd -1 "password"
|
||||
````
|
||||
|
||||
> Note: The switch to `openssl passwd` is the **number one** (`-1`) for using the MD5 based BSD password algorithm.
|
||||
|
||||
Insert the user into the database using the generated password hash:
|
||||
|
||||
````
|
||||
INSERT INTO icingaweb_user (name, active, password_hash) VALUES ('icingaadmin', 1, 'hash from openssl');
|
||||
````
|
||||
|
|
|
@ -26,7 +26,7 @@ repository either via git or http protocol using the following URLs:
|
|||
* http://git.icinga.org/icingaweb2.git
|
||||
|
||||
There is also a browsable version available at
|
||||
[gi.icinga.org](https://git.icinga.org/?p=icingaweb2.git;a=summary "Icinga Web 2 Git Repository").
|
||||
[git.icinga.org](https://git.icinga.org/?p=icingaweb2.git;a=summary "Icinga Web 2 Git Repository").
|
||||
This version also offers snapshots for easy download which you can use if you do not have git present on your system.
|
||||
|
||||
````
|
||||
|
|
|
@ -1,101 +1,53 @@
|
|||
# Preferences
|
||||
# <a id="preferences"></a> Preferences
|
||||
|
||||
Preferences are user based configuration for Icinga Web 2. For example max page
|
||||
items, languages or date time settings can controlled by users.
|
||||
Preferences are settings a user can set for his account only, for example his language and time zone.
|
||||
|
||||
# Architecture
|
||||
**Choosing Where to Store Preferences**
|
||||
|
||||
Preferences are initially loaded from a provider (ini files or database) and
|
||||
stored into session at login time. After this step preferences are only
|
||||
persisted to the configured backend, but never reloaded from them.
|
||||
Preferences can be stored either in INI files or in a MySQL or in a PostgreSQL database. By default, Icinga Web 2 stores
|
||||
preferences in INI files beneath Icinga Web 2's configuration directory.
|
||||
|
||||
# Configuration
|
||||
## <a id="preferences-configuration"></a> Configuration
|
||||
|
||||
Preferences can be configured in config.ini in **preferences** section, default
|
||||
settings are this:
|
||||
Where to store preferences is defined in the INI file **config/config.ini** in the *preferences* section.
|
||||
|
||||
[preferences]
|
||||
type=ini
|
||||
### <a id="preferences-configuration-ini"></a> Store Preferences in INI Files
|
||||
|
||||
The ini provider uses the directory **config/preferences** to create one ini
|
||||
file per user and persists the data into a single file. If you want to drop your
|
||||
preferences just drop the file from disk and you'll start with a new profile.
|
||||
If preferences are stored in INI Files, Icinga Web 2 automatically creates one file per user using the username as
|
||||
file name for storing preferences. A INI file is created once a user saves changed preferences the first time.
|
||||
The files are located beneath the `preferences` directory beneath Icinga Web 2's configuration directory.
|
||||
|
||||
## Database Provider
|
||||
For storing preferences in INI files you have to add the following section to the INI file **config/config.ini**:
|
||||
|
||||
To be more flexible in distributed setups you can store preferences in a
|
||||
database (pgsql or mysql), a typical configuration looks like the following
|
||||
example:
|
||||
```
|
||||
[preferences]
|
||||
type = ini
|
||||
````
|
||||
|
||||
[preferences]
|
||||
type=db
|
||||
resource=icingaweb-pgsql
|
||||
### <a id="preferences-configuration-db"></a> Store Preferences in a Database
|
||||
|
||||
## Null Provider
|
||||
In order to be more flexible in distributed setups you can store preferences in a MySQL or in a PostgreSQL database.
|
||||
For storing preferences in a database, you have to define a [database resource](#resources-configuration-database)
|
||||
which will be referenced as resource for the preferences storage.
|
||||
|
||||
The Null Provider discards all preferences and is mainly used as a fallback when no provider could be
|
||||
created (due to permission errors, database outtakes, etc.).
|
||||
Directive | Description
|
||||
------------------------|------------
|
||||
**type** | `db`
|
||||
**resource** | The name of the database resource defined in [resources.ini](resources).
|
||||
|
||||
[preferences]
|
||||
type=null
|
||||
**Example:**
|
||||
|
||||
If your preferences aren't stored it's best to take a look into the logfiles - errors during the preference setup
|
||||
are displayed as warnings here.
|
||||
```
|
||||
[preferences]
|
||||
type = db
|
||||
resource = icingaweb-mysql
|
||||
```
|
||||
|
||||
### Settings
|
||||
#### <a id="preferences-configuration-db-setup"></a> Database Setup
|
||||
|
||||
* **resource**: A reference to a database declared in *resources.ini*. Please read the chapter about
|
||||
resources for a detailed description about how to set up resources.
|
||||
For storing preferences in a database, you have to import one of the following database schemas:
|
||||
|
||||
### Preparation
|
||||
* **etc/schema/preferences.mysql.sql** (for **MySQL** database)
|
||||
* **etc/schema/preferences.pgsql.sql** (for **PostgreSQL** databases)
|
||||
|
||||
To use this feature you need a running database environment. After creating a
|
||||
database and a writable user you need to import the initial table file:
|
||||
|
||||
* etc/schema/preferences.mysql.sql (for mysql database)
|
||||
* etc/schema/preferemces.pgsql.sql (for postgres databases)
|
||||
|
||||
#### Example for mysql
|
||||
|
||||
# mysql -u root -p
|
||||
mysql> create database icingaweb;
|
||||
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON icingaweb.* TO \
|
||||
'icingaweb'@'localhost' IDENTIFIED BY 'icingaweb';
|
||||
mysql> exit
|
||||
# mysql -u root -p icingaweb < /path/to/icingaweb/etc/schema/preferences.mysql.sql
|
||||
|
||||
After following these steps above you can configure your preferences provider.
|
||||
|
||||
## Coding API
|
||||
|
||||
You can set, update or remove preferences using the Preference data object
|
||||
which is bound to the user. Here are some simple examples how to work with
|
||||
that:
|
||||
|
||||
$preferences = $user->getPreferences();
|
||||
// Get language with en_US as fallback
|
||||
$preferences->get('app.language', 'en_US');
|
||||
$preferences->set('app.language', 'de_DE');
|
||||
$preferences->remove('app.language');
|
||||
|
||||
// Using transactional mode
|
||||
$preferences->startTransaction();
|
||||
$preferences->set('test.pref1', 'pref1');
|
||||
$preferences->set('test.pref2', 'pref2');
|
||||
$preferences->remove('test.pref3');
|
||||
$preferemces->commit(); // Stores 3 changes in one operation
|
||||
|
||||
More information can be found in the api docs.
|
||||
|
||||
## Namespaces and behaviour
|
||||
|
||||
If you are using this API please obey the following rules:
|
||||
|
||||
* Use dotted notation for preferences
|
||||
* Namespaces starting with one context identifier
|
||||
* **app** as global identified (e.g. app.language)
|
||||
* **mymodule** for your module
|
||||
* **monitoring** for the monitoring module
|
||||
* Use preferences wisely (set only when needed and write small settings)
|
||||
* Use only simple data types, e.g. strings or numbers
|
||||
* If you need complex types you have to do it your self (e.g. serialization)
|
||||
After that you have to define the [database resource](#resources-configuration-database).
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
Icinga Web 2
|
||||
|
||||
@link https://www.icinga.org/icingaweb2/
|
||||
@copyright Copyright (c) 2013-%(YEAR)s Icinga Development Team (https://www.icinga.org)
|
||||
@license http://www.gnu.org/licenses/gpl-2.0.txt, or any later version
|
398
icingaweb2.spec
398
icingaweb2.spec
|
@ -1,237 +1,235 @@
|
|||
#/**
|
||||
# * This file is part of Icinga Web 2.
|
||||
# *
|
||||
# * Icinga Web 2 - Head for multiple monitoring backends.
|
||||
# * Copyright (C) 2014 Icinga Development Team
|
||||
# *
|
||||
# * This program is free software; you can redistribute it and/or
|
||||
# * modify it under the terms of the GNU General Public License
|
||||
# * as published by the Free Software Foundation; either version 2
|
||||
# * of the License, or (at your option) any later version.
|
||||
# *
|
||||
# * This program is distributed in the hope that it will be useful,
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# * GNU General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU General Public License
|
||||
# * along with this program; if not, write to the Free Software
|
||||
# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
# *
|
||||
# * @copyright 2014 Icinga Development Team <info@icinga.org>
|
||||
# * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
# * @author Icinga Development Team <info@icinga.org>
|
||||
# *
|
||||
# */
|
||||
|
||||
%define revision 1
|
||||
|
||||
%define configdir %{_sysconfdir}/%{name}
|
||||
%define sharedir %{_datadir}/%{name}
|
||||
%define prefixdir %{_datadir}/%{name}
|
||||
%define usermodparam -a -G
|
||||
%define logdir %{_localstatedir}/log/%{name}
|
||||
%define docdir %{sharedir}/doc
|
||||
|
||||
%if "%{_vendor}" == "suse"
|
||||
%define phpname php5
|
||||
%define phpzendname php5-ZendFramework
|
||||
%define apache2modphpname apache2-mod_php5
|
||||
%endif
|
||||
# SLE 11 = 1110
|
||||
%if 0%{?suse_version} == 1110
|
||||
%define phpname php53
|
||||
%define apache2modphpname apache2-mod_php53
|
||||
%define usermodparam -A
|
||||
%endif
|
||||
|
||||
%if "%{_vendor}" == "redhat"
|
||||
%define phpname php
|
||||
%define phpzendname php-ZendFramework
|
||||
%endif
|
||||
|
||||
# el5 requires newer php53 rather than php (5.1)
|
||||
%if 0%{?el5} || 0%{?rhel} == 5 || "%{?dist}" == ".el5"
|
||||
%define phpname php53
|
||||
%endif
|
||||
|
||||
%if "%{_vendor}" == "suse"
|
||||
%define apacheconfdir %{_sysconfdir}/apache2/conf.d
|
||||
%define apacheuser wwwrun
|
||||
%define apachegroup www
|
||||
%define extcmdfile %{_localstatedir}/run/icinga2/cmd/icinga.cmd
|
||||
%define livestatussocket %{_localstatedir}/run/icinga2/cmd/livestatus
|
||||
%endif
|
||||
%if "%{_vendor}" == "redhat"
|
||||
%define apacheconfdir %{_sysconfdir}/httpd/conf.d
|
||||
%define apacheuser apache
|
||||
%define apachegroup apache
|
||||
%define extcmdfile %{_localstatedir}/run/icinga2/cmd/icinga.cmd
|
||||
%define livestatussocket %{_localstatedir}/run/icinga2/cmd/livestatus
|
||||
%endif
|
||||
|
||||
Summary: Open Source host, service and network monitoring Web UI
|
||||
Name: icingaweb2
|
||||
Version: 0.0.1
|
||||
Release: %{revision}%{?dist}
|
||||
License: GPLv2
|
||||
Version: 2.0.0
|
||||
Release: 1.beta2%{?dist}
|
||||
Summary: Icinga Web 2
|
||||
Group: Applications/System
|
||||
URL: http://www.icinga.org
|
||||
License: GPL
|
||||
URL: https://icinga.org
|
||||
Source0: https://github.com/Icinga/%{name}/archive/v%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}
|
||||
Packager: Icinga Team <info@icinga.org>
|
||||
|
||||
%if "%{_vendor}" == "suse"
|
||||
AutoReqProv: Off
|
||||
%if 0%{?fedora} || 0%{?rhel}
|
||||
%define wwwconfigdir %{_sysconfdir}/httpd/conf.d
|
||||
%define wwwuser apache
|
||||
%if 0%{?rhel} == 5
|
||||
%define php php53
|
||||
%define php_cli php53-cli
|
||||
%else
|
||||
%define php php
|
||||
%define php_cli php-cli
|
||||
%endif
|
||||
%if 0%{rhel} == 6
|
||||
%define zend php-ZendFramework
|
||||
%else
|
||||
%define zend %{name}-vendor-Zend
|
||||
%endif
|
||||
%endif
|
||||
|
||||
Source: icingaweb2-%{version}.tar.gz
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
|
||||
BuildRequires: %{phpname} >= 5.3.0
|
||||
BuildRequires: %{phpname}-devel >= 5.3.0
|
||||
BuildRequires: %{phpname}-ldap
|
||||
BuildRequires: %{phpname}-pdo
|
||||
BuildRequires: %{phpzendname}
|
||||
%if "%{_vendor}" != "suse"
|
||||
BuildRequires: %{phpzendname}-Db-Adapter-Pdo
|
||||
BuildRequires: %{phpzendname}-Db-Adapter-Pdo-Mysql
|
||||
BuildRequires: %{phpzendname}-Db-Adapter-Pdo-Pgsql
|
||||
%endif
|
||||
|
||||
%if "%{_vendor}" == "redhat"
|
||||
%endif
|
||||
%if "%{_vendor}" == "suse"
|
||||
Requires: %{phpname}-devel >= 5.3.0
|
||||
BuildRequires: %{phpname}-json
|
||||
BuildRequires: %{phpname}-sockets
|
||||
BuildRequires: %{phpname}-dom
|
||||
%endif
|
||||
|
||||
Requires: %{phpname} >= 5.3.0
|
||||
Requires: %{phpzendname}
|
||||
Requires: %{phpname}-ldap
|
||||
Requires: %{phpname}-pdo
|
||||
%if "%{_vendor}" == "redhat"
|
||||
Requires: %{phpname}-common
|
||||
Requires: %{phpzendname}-Db-Adapter-Pdo
|
||||
Requires: %{phpzendname}-Db-Adapter-Pdo-Mysql
|
||||
Requires: php-pear
|
||||
%endif
|
||||
%if "%{_vendor}" == "suse"
|
||||
Requires: %{phpname}-pear
|
||||
Requires: %{phpname}-dom
|
||||
Requires: %{phpname}-tokenizer
|
||||
Requires: %{phpname}-gettext
|
||||
Requires: %{phpname}-ctype
|
||||
Requires: %{phpname}-json
|
||||
Requires: %{apache2modphpname}
|
||||
%endif
|
||||
|
||||
Requires: php-Icinga
|
||||
Requires(pre): shadow-utils
|
||||
Requires: %{name}-common = %{version}-%{release}
|
||||
Requires: php-Icinga = %{version}-%{release}
|
||||
Requires: %{name}-vendor-dompdf
|
||||
Requires: %{name}-vendor-HTMLPurifier
|
||||
Requires: %{name}-vendor-JShrink
|
||||
Requires: %{name}-vendor-lessphp
|
||||
Requires: %{name}-vendor-Parsedown
|
||||
Requires: %{zend}
|
||||
|
||||
|
||||
%description
|
||||
Icinga Web 2 for Icinga 2 or Icinga 1.x using multiple backends
|
||||
for example DB IDO.
|
||||
Icinga Web 2
|
||||
|
||||
|
||||
%define basedir %{_datadir}/%{name}
|
||||
%define bindir %{_bindir}
|
||||
%define configdir %{_sysconfdir}/%{name}
|
||||
%define logdir %{_localstatedir}/log/%{name}
|
||||
%define phpdir %{_datadir}/php
|
||||
%define icingawebgroup icingaweb2
|
||||
|
||||
|
||||
%package common
|
||||
Summary: Common files for Icinga Web 2 and the Icinga CLI
|
||||
Group: Applications/System
|
||||
|
||||
%description common
|
||||
Common files for Icinga Web 2 and the Icinga CLI
|
||||
|
||||
|
||||
%package -n php-Icinga
|
||||
Summary: Icinga Web 2 PHP library
|
||||
Group: Development/Libraries
|
||||
Requires: %{php} >= 5.3.0
|
||||
|
||||
%description -n php-Icinga
|
||||
Icinga Web 2 PHP library
|
||||
|
||||
|
||||
%package -n icingacli
|
||||
Summary: Icinga CLI
|
||||
Group: Applications/System
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
Requires: php-Icinga
|
||||
Requires: %{name}-common = %{version}-%{release}
|
||||
Requires: php-Icinga = %{version}-%{release}
|
||||
Requires: %{php_cli} >= 5.3.0
|
||||
|
||||
%description -n icingacli
|
||||
Icinga CLI using php-Icinga Icinga Web 2 backend.
|
||||
|
||||
%package -n php-Icinga
|
||||
Summary: Icinga Web 2 PHP Libraries
|
||||
Group: Applications/System
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
Requires: %{phpname} >= 5.3.0
|
||||
Requires: %{phpzendname}
|
||||
Icinga CLI
|
||||
|
||||
|
||||
%description -n php-Icinga
|
||||
Icinga Web 2 PHP Libraries required by the web frontend and cli tool.
|
||||
%package vendor-dompdf
|
||||
Version: 0.6.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Icinga Web 2 vendor library dompdf
|
||||
Group: Development/Libraries
|
||||
Requires: %{php} >= 5.3.0
|
||||
|
||||
%description vendor-dompdf
|
||||
Icinga Web 2 vendor library dompdf
|
||||
|
||||
|
||||
%package vendor-HTMLPurifier
|
||||
Version: 4.6.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Icinga Web 2 vendor library HTMLPurifier
|
||||
Group: Development/Libraries
|
||||
Requires: %{php} >= 5.3.0
|
||||
|
||||
%description vendor-HTMLPurifier
|
||||
Icinga Web 2 vendor library HTMLPurifier
|
||||
|
||||
|
||||
%package vendor-JShrink
|
||||
Version: 1.0.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Icinga Web 2 vendor library JShrink
|
||||
Group: Development/Libraries
|
||||
Requires: %{php} >= 5.3.0
|
||||
|
||||
%description vendor-JShrink
|
||||
Icinga Web 2 vendor library JShrink
|
||||
|
||||
|
||||
%package vendor-lessphp
|
||||
Version: 0.4.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Icinga Web 2 vendor library lessphp
|
||||
Group: Development/Libraries
|
||||
Requires: %{php} >= 5.3.0
|
||||
|
||||
%description vendor-lessphp
|
||||
Icinga Web 2 vendor library lessphp
|
||||
|
||||
|
||||
%package vendor-Parsedown
|
||||
Version: 1.0.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Icinga Web 2 vendor library Parsedown
|
||||
Group: Development/Libraries
|
||||
Requires: %{php} >= 5.3.0
|
||||
|
||||
%description vendor-Parsedown
|
||||
Icinga Web 2 vendor library Parsedown
|
||||
|
||||
|
||||
%package vendor-Zend
|
||||
Version: 1.12.9
|
||||
Release: 1%{?dist}
|
||||
Summary: Icinga Web 2 vendor library Zend Framework
|
||||
Group: Development/Libraries
|
||||
Requires: %{php} >= 5.3.0
|
||||
|
||||
%description vendor-Zend
|
||||
Icinga Web 2 vendor library Zend
|
||||
|
||||
|
||||
%prep
|
||||
#VERSION=0.0.1; git archive --format=tar --prefix=icingaweb2-$VERSION/ HEAD | gzip >icingaweb2-$VERSION.tar.gz
|
||||
%setup -q -n %{name}-%{version}
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
|
||||
%install
|
||||
[ "%{buildroot}" != "/" ] && [ -d "%{buildroot}" ] && rm -rf %{buildroot}
|
||||
|
||||
# prepare configuration for sub packages
|
||||
|
||||
# install rhel apache config
|
||||
install -D -m0644 packages/files/apache/icingaweb.conf %{buildroot}/%{apacheconfdir}/icingaweb.conf
|
||||
|
||||
# install public, library, modules
|
||||
%{__mkdir} -p %{buildroot}/%{sharedir}
|
||||
%{__mkdir} -p %{buildroot}/%{logdir}
|
||||
%{__mkdir} -p %{buildroot}/%{docdir}
|
||||
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}
|
||||
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/dashboard
|
||||
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/modules
|
||||
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/modules/monitoring
|
||||
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/enabledModules
|
||||
|
||||
# make sure to install local icingacli for setup wizard token generation & webserver config
|
||||
%{__cp} -r application doc library modules public bin %{buildroot}/%{sharedir}/
|
||||
|
||||
# enable the monitoring module by default
|
||||
ln -s %{sharedir}/modules/monitoring %{buildroot}/%{_sysconfdir}/%{name}/enabledModules/monitoring
|
||||
## config
|
||||
|
||||
# symlink icingacli
|
||||
mkdir -p %{buildroot}/usr/bin
|
||||
ln -sf %{sharedir}/bin/icingacli %{buildroot}/usr/bin/icingacli
|
||||
rm -rf %{buildroot}
|
||||
mkdir -p %{buildroot}/{%{basedir}/{modules,library,public},%{bindir},%{configdir},%{logdir},%{phpdir},%{wwwconfigdir}}
|
||||
cp -prv application doc var %{buildroot}/%{basedir}
|
||||
cp -prv modules/{monitoring,setup} %{buildroot}/%{basedir}/modules
|
||||
cp -prv library/Icinga %{buildroot}/%{phpdir}
|
||||
cp -prv library/vendor %{buildroot}/%{basedir}/library
|
||||
cp -prv public/{css,img,js,error_norewrite.html} %{buildroot}/%{basedir}/public
|
||||
cp -pv packages/files/apache/icingaweb2.conf %{buildroot}/%{wwwconfigdir}/icingaweb2.conf
|
||||
cp -pv packages/files/bin/icingacli %{buildroot}/%{bindir}
|
||||
cp -pv packages/files/public/index.php %{buildroot}/%{basedir}/public
|
||||
|
||||
%pre
|
||||
# Add apacheuser in the icingacmd group
|
||||
# If the group exists, add the apacheuser in the icingacmd group.
|
||||
# It is not neccessary that icinga2-web is installed on the same system as
|
||||
# icinga and only on systems with icinga installed the icingacmd
|
||||
# group exists. In all other cases the user used for ssh access has
|
||||
# to be added to the icingacmd group on the remote icinga server.
|
||||
getent group icingacmd > /dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
%{_sbindir}/usermod %{usermodparam} icingacmd %{apacheuser}
|
||||
fi
|
||||
|
||||
%preun
|
||||
|
||||
%post
|
||||
getent group icingacmd >/dev/null || groupadd -r icingacmd
|
||||
usermod -a -G icingacmd,%{icingawebgroup} %{wwwuser}
|
||||
exit 0
|
||||
|
||||
%clean
|
||||
[ "%{buildroot}" != "/" ] && [ -d "%{buildroot}" ] && rm -rf %{buildroot}
|
||||
rm -rf %{buildroot}
|
||||
|
||||
%files
|
||||
# main dirs
|
||||
%defattr(-,root,root)
|
||||
%doc etc/schema doc packages/RPM.md
|
||||
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/public
|
||||
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/modules
|
||||
# configs
|
||||
%{basedir}/application/controllers
|
||||
%{basedir}/application/fonts
|
||||
%{basedir}/application/forms
|
||||
%{basedir}/application/layouts
|
||||
%{basedir}/application/views
|
||||
%{basedir}/doc
|
||||
%{basedir}/modules
|
||||
%{basedir}/public
|
||||
%{wwwconfigdir}/icingaweb2.conf
|
||||
%attr(2775,root,%{icingawebgroup}) %dir %{logdir}
|
||||
|
||||
|
||||
%pre common
|
||||
getent group %{icingawebgroup} >/dev/null || groupadd -r %{icingawebgroup}
|
||||
exit 0
|
||||
|
||||
%files common
|
||||
%defattr(-,root,root)
|
||||
%config(noreplace) %attr(-,root,root) %{apacheconfdir}/icingaweb.conf
|
||||
%config(noreplace) %attr(-,%{apacheuser},%{apachegroup}) %{configdir}
|
||||
# logs
|
||||
%attr(2775,%{apacheuser},%{apachegroup}) %dir %{logdir}
|
||||
# shipped docs
|
||||
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/doc
|
||||
%{basedir}/application/locale
|
||||
%dir %{basedir}/modules
|
||||
%attr(2770,root,%{icingawebgroup}) %config(noreplace) %{configdir}
|
||||
|
||||
|
||||
%files -n php-Icinga
|
||||
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/application
|
||||
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/library
|
||||
%defattr(-,root,root)
|
||||
%{phpdir}/Icinga
|
||||
|
||||
|
||||
%files -n icingacli
|
||||
%attr(0755,root,root) /usr/bin/icingacli
|
||||
%attr(0755,root,root) %{sharedir}/bin/icingacli
|
||||
%attr(0755,root,root) %{sharedir}/bin/license_writer.py
|
||||
%defattr(-,root,root)
|
||||
%{basedir}/application/clicommands
|
||||
%attr(0755,root,root) %{bindir}/icingacli
|
||||
|
||||
%changelog
|
||||
|
||||
%files vendor-dompdf
|
||||
%defattr(-,root,root)
|
||||
%{basedir}/library/vendor/dompdf
|
||||
|
||||
|
||||
%files vendor-HTMLPurifier
|
||||
%defattr(-,root,root)
|
||||
%{basedir}/library/vendor/HTMLPurifier
|
||||
|
||||
|
||||
%files vendor-JShrink
|
||||
%defattr(-,root,root)
|
||||
%{basedir}/library/vendor/JShrink
|
||||
|
||||
|
||||
%files vendor-lessphp
|
||||
%defattr(-,root,root)
|
||||
%{basedir}/library/vendor/lessphp
|
||||
|
||||
|
||||
%files vendor-Parsedown
|
||||
%defattr(-,root,root)
|
||||
%{basedir}/library/vendor/Parsedown
|
||||
|
||||
|
||||
%files vendor-Zend
|
||||
%defattr(-,root,root)
|
||||
%{basedir}/library/vendor/Zend
|
||||
|
|
|
@ -113,6 +113,13 @@ abstract class ApplicationBootstrap
|
|||
*/
|
||||
protected $isWeb = false;
|
||||
|
||||
/**
|
||||
* Whether Icinga Web 2 requires setup
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
protected $requiresSetup = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -133,7 +140,7 @@ abstract class ApplicationBootstrap
|
|||
if (array_key_exists('ICINGAWEB_CONFIGDIR', $_SERVER)) {
|
||||
$configDir = $_SERVER['ICINGAWEB_CONFIGDIR'];
|
||||
} else {
|
||||
$configDir = '/etc/icingaweb';
|
||||
$configDir = '/etc/icingaweb2';
|
||||
}
|
||||
}
|
||||
$canonical = realpath($configDir);
|
||||
|
@ -333,7 +340,7 @@ abstract class ApplicationBootstrap
|
|||
/**
|
||||
* Setup Icinga auto loader
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
public function setupAutoloader()
|
||||
{
|
||||
|
@ -366,7 +373,7 @@ abstract class ApplicationBootstrap
|
|||
/**
|
||||
* Setup module manager
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupModuleManager()
|
||||
{
|
||||
|
@ -378,25 +385,10 @@ abstract class ApplicationBootstrap
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all core modules
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function loadCoreModules()
|
||||
{
|
||||
try {
|
||||
$this->moduleManager->loadCoreModules();
|
||||
} catch (NotReadableError $e) {
|
||||
Logger::error(new IcingaException('Cannot load core modules. An exception was thrown:', $e));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all enabled modules
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
protected function loadEnabledModules()
|
||||
{
|
||||
|
@ -408,10 +400,44 @@ abstract class ApplicationBootstrap
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the setup module if Icinga Web 2 requires setup
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function loadSetupModuleIfNecessary()
|
||||
{
|
||||
if (! @file_exists($this->config->resolvePath('config.ini'))) {
|
||||
$this->requiresSetup = true;
|
||||
$this->moduleManager->loadModule('setup');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether Icinga Web 2 requires setup
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function requiresSetup()
|
||||
{
|
||||
return $this->requiresSetup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the setup token exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setupTokenExists()
|
||||
{
|
||||
return @file_exists($this->config->resolvePath('setup.token'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup default logging
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupLogging()
|
||||
{
|
||||
|
@ -428,7 +454,7 @@ abstract class ApplicationBootstrap
|
|||
/**
|
||||
* Load Configuration
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
protected function loadConfig()
|
||||
{
|
||||
|
@ -447,7 +473,7 @@ abstract class ApplicationBootstrap
|
|||
/**
|
||||
* Error handling configuration
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupErrorHandling()
|
||||
{
|
||||
|
@ -473,7 +499,7 @@ abstract class ApplicationBootstrap
|
|||
/**
|
||||
* Set up logger
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupLogger()
|
||||
{
|
||||
|
@ -490,7 +516,7 @@ abstract class ApplicationBootstrap
|
|||
/**
|
||||
* Set up the resource factory
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupResourceFactory()
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ class Cli extends ApplicationBootstrap
|
|||
->setupLogger()
|
||||
->setupResourceFactory()
|
||||
->setupModuleManager()
|
||||
->loadCoreModules();
|
||||
->loadSetupModuleIfNecessary();
|
||||
}
|
||||
|
||||
protected function setupLogging()
|
||||
|
|
|
@ -6,10 +6,8 @@ namespace Icinga\Application;
|
|||
|
||||
require_once dirname(__FILE__) . '/ApplicationBootstrap.php';
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
/**
|
||||
* Use this if you want to make use of Icinga funtionality in other web projects
|
||||
* Use this if you want to make use of Icinga functionality in other web projects
|
||||
*
|
||||
* Usage example:
|
||||
* <code>
|
||||
|
|
|
@ -68,18 +68,6 @@ class Manager
|
|||
*/
|
||||
private $modulePaths = array();
|
||||
|
||||
/**
|
||||
* The core modules
|
||||
*
|
||||
* Core modules do not need to be enabled to load and cannot be disabled
|
||||
* by the user. This must not be writable programmatically!
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $coreModules = array(
|
||||
'setup'
|
||||
);
|
||||
|
||||
/**
|
||||
* Create a new instance of the module manager
|
||||
*
|
||||
|
@ -170,21 +158,7 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* Try to set all core modules in loaded state
|
||||
*
|
||||
* @return self
|
||||
* @see Manager::loadModule()
|
||||
*/
|
||||
public function loadCoreModules()
|
||||
{
|
||||
foreach ($this->coreModules as $name) {
|
||||
$this->loadModule($name);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to set all enabled modules in loaded state
|
||||
* Try to set all enabled modules in loaded sate
|
||||
*
|
||||
* @return self
|
||||
* @see Manager::loadModule()
|
||||
|
@ -239,8 +213,6 @@ class Manager
|
|||
'Cannot enable module "%s". Module is not installed.',
|
||||
$name
|
||||
);
|
||||
} elseif (in_array($name, $this->coreModules)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
clearstatcache(true);
|
||||
|
@ -458,7 +430,7 @@ class Manager
|
|||
}
|
||||
|
||||
$installed = $this->listInstalledModules();
|
||||
foreach (array_diff($installed, $this->coreModules) as $name) {
|
||||
foreach ($installed as $name) {
|
||||
$info[$name] = (object) array(
|
||||
'name' => $name,
|
||||
'path' => $this->installedBaseDirs[$name],
|
||||
|
|
|
@ -104,7 +104,7 @@ class Web extends ApplicationBootstrap
|
|||
->setupZendMvc()
|
||||
->setupFormNamespace()
|
||||
->setupModuleManager()
|
||||
->loadCoreModules()
|
||||
->loadSetupModuleIfNecessary()
|
||||
->loadEnabledModules()
|
||||
->setupRoute()
|
||||
->setupPagination();
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\File;
|
||||
|
||||
use FilterIterator;
|
||||
use Iterator;
|
||||
|
||||
/**
|
||||
* Iterator over files having a specific file extension
|
||||
*
|
||||
* Usage example:
|
||||
* <code>
|
||||
* <?php
|
||||
*
|
||||
* namespace Icinga\Example;
|
||||
*
|
||||
* use RecursiveDirectoryIterator;
|
||||
* use RecursiveIteratorIterator;
|
||||
* use Icinga\File\FileExtensionFilterIterator;
|
||||
*
|
||||
* $markdownFiles = new FileExtensionFilterIterator(
|
||||
* new RecursiveIteratorIterator(
|
||||
* new RecursiveDirectoryIterator(__DIR__),
|
||||
* RecursiveIteratorIterator::SELF_FIRST
|
||||
* ),
|
||||
* 'md'
|
||||
* );
|
||||
* </code>
|
||||
*/
|
||||
class FileExtensionFilterIterator extends FilterIterator
|
||||
{
|
||||
/**
|
||||
* The extension to filter for
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
protected $extension;
|
||||
|
||||
/**
|
||||
* Create a new FileExtensionFilterIterator
|
||||
*
|
||||
* @param Iterator $iterator Apply filter to this iterator
|
||||
* @param string $extension The file extension to filter for. The file extension may not contain the leading dot
|
||||
*/
|
||||
public function __construct(Iterator $iterator, $extension)
|
||||
{
|
||||
$this->extension = '.' . ltrim(strtolower((string) $extension), '.');
|
||||
parent::__construct($iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept files which match the file extension to filter for
|
||||
*
|
||||
* @return bool Whether the current element of the iterator is acceptable
|
||||
* through this filter
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
$current = $this->current();
|
||||
/* @var $current \SplFileInfo */
|
||||
if (! $current->isFile()) {
|
||||
return false;
|
||||
}
|
||||
// SplFileInfo::getExtension() is only available since PHP 5 >= 5.3.6
|
||||
$filename = $current->getFilename();
|
||||
$sfx = substr($filename, -strlen($this->extension));
|
||||
return $sfx === false ? false : strtolower($sfx) === $this->extension;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}
|
||||
|
||||
namespace Icinga\File;
|
||||
|
||||
use FilterIterator;
|
||||
|
||||
/**
|
||||
* Iterator over non-empty files
|
||||
*
|
||||
* Usage example:
|
||||
* <code>
|
||||
* <?php
|
||||
*
|
||||
* namespace Icinga\Example;
|
||||
*
|
||||
* use RecursiveDirectoryIterator;
|
||||
* use RecursiveIteratorIterator;
|
||||
* use Icinga\File\NonEmptyFilterIterator;
|
||||
*
|
||||
* $nonEmptyFiles = new NonEmptyFileIterator(
|
||||
* new RecursiveIteratorIterator(
|
||||
* new RecursiveDirectoryIterator(__DIR__),
|
||||
* RecursiveIteratorIterator::SELF_FIRST
|
||||
* )
|
||||
* );
|
||||
* </code>
|
||||
*/
|
||||
class NonEmptyFileIterator extends FilterIterator
|
||||
{
|
||||
/**
|
||||
* Accept non-empty files
|
||||
*
|
||||
* @return bool Whether the current element of the iterator is acceptable
|
||||
* through this filter
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
$current = $this->current();
|
||||
/** @type $current \SplFileInfo */
|
||||
if (! $current->isFile()
|
||||
|| $current->getSize() === 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -23,16 +23,17 @@ class String
|
|||
}
|
||||
|
||||
/**
|
||||
* Uppercase the first character of each word in a string assuming and removing the underscore as word separator
|
||||
* Uppercase the first character of each word in a string
|
||||
*
|
||||
* Converts 'first_name' to 'firstName' for example.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $separator Word separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function cname($name)
|
||||
public static function cname($name, $separator = '_')
|
||||
{
|
||||
return str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($name))));
|
||||
return str_replace(' ', '', ucwords(str_replace($separator, ' ', strtolower($name))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
namespace Icinga\Util;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
|
@ -34,8 +33,8 @@ class Translator
|
|||
*
|
||||
* Falls back to the default domain in case the string cannot be translated using the given domain
|
||||
*
|
||||
* @param string $text The string to translate
|
||||
* @param string $domain The primary domain to use
|
||||
* @param string $text The string to translate
|
||||
* @param string $domain The primary domain to use
|
||||
* @param string|null $context Optional parameter for context based translation
|
||||
*
|
||||
* @return string The translated string
|
||||
|
@ -64,7 +63,7 @@ class Translator
|
|||
*
|
||||
* @param string $textSingular The string in singular form to translate
|
||||
* @param string $textPlural The string in plural form to translate
|
||||
* @param integer $number The number to get the plural or singular string
|
||||
* @param integer $number The amount to determine from whether to return singular or plural
|
||||
* @param string $domain The primary domain to use
|
||||
* @param string|null $context Optional parameter for context based translation
|
||||
*
|
||||
|
|
|
@ -270,7 +270,7 @@ class ActionController extends Zend_Controller_Action
|
|||
/**
|
||||
* Redirect to the login path
|
||||
*
|
||||
* @param string $afterLogin The action to call when the login was successful. Defaults to '/index/welcome'
|
||||
* @param Url $afterLogin The action to call when the login was successful. Defaults to '/index/welcome'
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,7 @@ use Zend_Config;
|
|||
use Zend_Form;
|
||||
use Zend_View_Interface;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Util\Translator;
|
||||
use Icinga\Web\Form\Decorator\NoScriptApply;
|
||||
use Icinga\Web\Form\Element\CsrfCounterMeasure;
|
||||
|
||||
|
@ -147,7 +148,7 @@ class Form extends Zend_Form
|
|||
/**
|
||||
* Set a callback that is called instead of this form's onSuccess method
|
||||
*
|
||||
* It is called using the following signature: (Request $request, Form $form).
|
||||
* It is called using the following signature: (Form $this).
|
||||
*
|
||||
* @param callable $onSuccess Callback
|
||||
*
|
||||
|
@ -804,6 +805,58 @@ class Form extends Zend_Form
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation domain for this form
|
||||
*
|
||||
* The returned translation domain is either determined based on this form's qualified name or it is the default
|
||||
* 'icinga' domain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTranslationDomain()
|
||||
{
|
||||
$parts = explode('\\', get_called_class());
|
||||
if ($parts[1] === 'Module') {
|
||||
// Assume format Icinga\Module\ModuleName\Forms\...
|
||||
return strtolower($parts[2]);
|
||||
}
|
||||
return 'icinga';
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a string
|
||||
*
|
||||
* @param string $text The string to translate
|
||||
* @param string|null $context Optional parameter for context based translation
|
||||
*
|
||||
* @return string The translated string
|
||||
*/
|
||||
protected function translate($text, $context = null)
|
||||
{
|
||||
return Translator::translate($text, $this->getTranslationDomain(), $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a plural string
|
||||
*
|
||||
* @param string $textSingular The string in singular form to translate
|
||||
* @param string $textPlural The string in plural form to translate
|
||||
* @param integer $number The amount to determine from whether to return singular or plural
|
||||
* @param string|null $context Optional parameter for context based translation
|
||||
*
|
||||
* @return string The translated string
|
||||
*/
|
||||
protected function translatePlural($textSingular, $textPlural, $number, $context = null)
|
||||
{
|
||||
return Translator::translatePlural(
|
||||
$textSingular,
|
||||
$textPlural,
|
||||
$number,
|
||||
$this->getTranslationDomain(),
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render this form
|
||||
*
|
||||
|
|
|
@ -248,7 +248,8 @@ class Menu implements RecursiveIterator
|
|||
|
||||
$section->add(t('Logout'), array(
|
||||
'url' => 'authentication/logout',
|
||||
'priority' => 700
|
||||
'priority' => 700,
|
||||
'renderer' => 'ForeignMenuItemRenderer'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -366,7 +367,7 @@ class Menu implements RecursiveIterator
|
|||
/**
|
||||
* Return the url of this menu
|
||||
*
|
||||
* @return string
|
||||
* @return Url
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Menu;
|
||||
|
||||
use Icinga\Web\Menu;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
/**
|
||||
* A menu item with a link that surpasses the regular navigation link behavior
|
||||
*/
|
||||
class ForeignMenuItemRenderer implements MenuItemRenderer {
|
||||
|
||||
public function render(Menu $menu)
|
||||
{
|
||||
return sprintf(
|
||||
'<a href="%s" target="_self">%s%s<span></span></a>',
|
||||
$menu->getUrl() ?: '#',
|
||||
$menu->getIcon() ? '<img src="' . Url::fromPath($menu->getIcon()) . '" class="icon" /> ' : '',
|
||||
htmlspecialchars($menu->getTitle())
|
||||
);
|
||||
}
|
||||
}
|
|
@ -78,8 +78,9 @@ class PhpSession extends Session
|
|||
}
|
||||
}
|
||||
|
||||
if (!is_writable(session_save_path())) {
|
||||
throw new ConfigurationError('Can\'t save session');
|
||||
$sessionSavePath = session_save_path();
|
||||
if (session_module_name() === 'files' && !is_writable($sessionSavePath)) {
|
||||
throw new ConfigurationError("Can't save session, path '$sessionSavePath' is not writable.");
|
||||
}
|
||||
|
||||
if ($this->exists()) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
namespace Icinga\Web\Widget\Chart;
|
||||
|
||||
use Icinga\Chart\PieChart;
|
||||
use Icinga\Module\Monitoring\Plugin\PerfdataSet;
|
||||
use Icinga\Web\Widget\AbstractWidget;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Util\Format;
|
||||
|
@ -28,36 +29,23 @@ class InlinePie extends AbstractWidget
|
|||
const NUMBER_FORMAT_RATIO = 'ratio';
|
||||
|
||||
/**
|
||||
* The template string used for rendering this widget
|
||||
* The template string used for rendering this widget
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $template =<<<'EOD'
|
||||
<span
|
||||
class="sparkline"
|
||||
sparkTitle="{title}"
|
||||
sparkWidth="{width}"
|
||||
sparkHeight="{height}"
|
||||
sparkBorderWidth="{borderWidth}"
|
||||
sparkBorderColor="{borderColor}"
|
||||
sparkTooltipChartTitle="{title}"
|
||||
style="{style}"
|
||||
labels="{labels}"
|
||||
formatted="{formatted}"
|
||||
hideEmptyLabel={hideEmptyLabel}
|
||||
values="{data}"
|
||||
tooltipFormat="{tooltipFormat}"
|
||||
sparkSliceColors="[{colors}]"
|
||||
sparkType="pie"></span>
|
||||
<noscript>
|
||||
<img class="inlinepie"
|
||||
title="{title}" src="{url}" style="position: relative; top: 10px; width: {width}px; height: {height}px; {style}"
|
||||
data-icinga-colors="{colors}" data-icinga-values="{data}"
|
||||
/>
|
||||
</noscript>
|
||||
<span sparkType="pie" class="sparkline {class}" {title} {size} sparkSliceColors="[{colors}]" values="{data}">
|
||||
</span>
|
||||
{noscript}
|
||||
EOD;
|
||||
|
||||
private $noscript =<<<'EOD'
|
||||
<noscript>
|
||||
<img class="inlinepie {class}" {title} src="{url}" data-icinga-colors="{colors}" data-icinga-values="{data}"/>
|
||||
</noscript>
|
||||
EOD;
|
||||
|
||||
|
||||
/**
|
||||
* @var Url
|
||||
*/
|
||||
|
@ -68,35 +56,7 @@ EOD;
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
private $colors = array('#44bb77', '#ffaa44', '#ff5566', '#ddccdd');
|
||||
|
||||
/**
|
||||
* The width of the rendered chart
|
||||
*
|
||||
* @var int The value in px
|
||||
*/
|
||||
private $width = 16;
|
||||
|
||||
/**
|
||||
* The height of the rendered chart
|
||||
*
|
||||
* @var int The value in px
|
||||
*/
|
||||
private $height = 16;
|
||||
|
||||
/**
|
||||
* PieChart border width
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $borderWidth = 1;
|
||||
|
||||
/**
|
||||
* The color of the border
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $borderColor = '#fff';
|
||||
private $colors = array('#049BAF', '#ffaa44', '#ff5566', '#ddccdd');
|
||||
|
||||
/**
|
||||
* The title of the chart
|
||||
|
@ -106,11 +66,9 @@ EOD;
|
|||
private $title;
|
||||
|
||||
/**
|
||||
* The style for the HtmlElement
|
||||
*
|
||||
* @var string
|
||||
* @var
|
||||
*/
|
||||
private $style = '';
|
||||
private $size;
|
||||
|
||||
/**
|
||||
* The data displayed by the pie-chart
|
||||
|
@ -120,45 +78,9 @@ EOD;
|
|||
private $data;
|
||||
|
||||
/**
|
||||
* The labels to display for each data set
|
||||
*
|
||||
* @var array
|
||||
* @var
|
||||
*/
|
||||
private $labels = array();
|
||||
|
||||
/**
|
||||
* If the tooltip for the "empty" area should be hidden
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $hideEmptyLabel = false;
|
||||
|
||||
/**
|
||||
* The format string used to display tooltips
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $tooltipFormat = '<b>{{title}}</b></br> {{label}}: {{formatted}} ({{percent}}%)';
|
||||
|
||||
/**
|
||||
* The number format used to render numeric values in tooltips
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $format = self::NUMBER_FORMAT_NONE;
|
||||
|
||||
/**
|
||||
* Set if the tooltip for the empty area should be hidden
|
||||
*
|
||||
* @param bool $hide Whether to hide the empty area
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHideEmptyLabel($hide = true)
|
||||
{
|
||||
$this->hideEmptyLabel = $hide;
|
||||
return $this;
|
||||
}
|
||||
private $class = '';
|
||||
|
||||
/**
|
||||
* Set the data to be displayed.
|
||||
|
@ -175,24 +97,36 @@ EOD;
|
|||
}
|
||||
|
||||
/**
|
||||
* The labels to be displayed in the pie-chart
|
||||
* Set the size of the inline pie
|
||||
*
|
||||
* @param mixed $label The label of the displayed value, or null for no labels
|
||||
* @param int $size Sets both, the height and width
|
||||
*
|
||||
* @return $this
|
||||
* @return $this
|
||||
*/
|
||||
public function setLabel($label)
|
||||
public function setSize($size = null)
|
||||
{
|
||||
if (is_array($label)) {
|
||||
$this->url->setParam('labels', implode(',', array_keys($label)));
|
||||
} elseif ($label != null) {
|
||||
$labelArr = array($label, $label, $label, '');
|
||||
$this->url->setParam('labels', implode(',', $labelArr));
|
||||
$label = $labelArr;
|
||||
} else {
|
||||
$this->url->removeKey('labels');
|
||||
}
|
||||
$this->labels = $label;
|
||||
$this->size = $size;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not display the NoScript fallback html
|
||||
*/
|
||||
public function disableNoScript()
|
||||
{
|
||||
$this->noscript = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class to define the
|
||||
*
|
||||
* @param $class
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSparklineClass($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -214,105 +148,6 @@ EOD;
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the used number format
|
||||
*
|
||||
* @param $format string 'bytes' or 'time'
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setNumberFormat($format)
|
||||
{
|
||||
$this->format = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A format string used to render the content of the piechart tooltips
|
||||
*
|
||||
* Placeholders using curly braces '{FOO}' are replace with their specific values. The format
|
||||
* String may contain HTML-Markup. The available replaceable values are:
|
||||
* <ul>
|
||||
* <li><b>label</b>: The description for the current value </li>
|
||||
* <li><b>formatted</b>: A string representing the formatted value </li>
|
||||
* <li><b>value</b>: The raw (non-formatted) value used to render the piechart </li>
|
||||
* <li><b>percent</b>: The percentage of the current value </li>
|
||||
* </ul>
|
||||
* Note: Changes will only affect JavaScript sparklines and not the SVG charts used for fallback
|
||||
*
|
||||
* @param $format
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTooltipFormat($format)
|
||||
{
|
||||
$this->tooltipFormat = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height
|
||||
*
|
||||
* @param $height
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeight($height)
|
||||
{
|
||||
$this->height = $height;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the border width of the pie chart
|
||||
*
|
||||
* @param float $width Width in px
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBorderWidth($width)
|
||||
{
|
||||
$this->borderWidth = $width;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the pie chart border
|
||||
*
|
||||
* @param string $col The color string
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBorderColor($col)
|
||||
{
|
||||
$this->borderColor = $col;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width
|
||||
*
|
||||
* @param $width
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setWidth($width)
|
||||
{
|
||||
$this->width = $width;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the styling of the created HtmlElement
|
||||
*
|
||||
* @param string $style
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStyle($style)
|
||||
{
|
||||
$this->style = $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title of the displayed Data
|
||||
*
|
||||
|
@ -322,7 +157,7 @@ EOD;
|
|||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->title = 'title="' . htmlspecialchars($title) . '"';
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -335,13 +170,10 @@ EOD;
|
|||
*/
|
||||
public function __construct(array $data, $title, $colors = null)
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->setTitle($title);
|
||||
$this->url = Url::fromPath('svg/chart.php');
|
||||
if (array_key_exists('data', $data)) {
|
||||
$this->data = $data['data'];
|
||||
if (array_key_exists('labels', $data)) {
|
||||
$this->labels = $data['labels'];
|
||||
}
|
||||
if (array_key_exists('colors', $data)) {
|
||||
$this->colors = $data['colors'];
|
||||
}
|
||||
|
@ -354,21 +186,6 @@ EOD;
|
|||
$this->setColors($this->colors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a serialization containing the current label array
|
||||
*
|
||||
* @return string A serialized array of labels
|
||||
*/
|
||||
private function createLabelString ()
|
||||
{
|
||||
$labels = $this->labels;
|
||||
foreach ($labels as $key => $label) {
|
||||
$labels[$key] = str_replace('|', '', $label);
|
||||
}
|
||||
return isset($this->labels) && is_array($this->labels) ? implode('|', $this->labels) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders this widget via the given view and returns the
|
||||
* HTML as a string
|
||||
|
@ -382,11 +199,11 @@ EOD;
|
|||
$pie->alignTopLeft();
|
||||
$pie->disableLegend();
|
||||
$pie->drawPie(array(
|
||||
'data' => $this->data, 'colors' => $this->colors, 'labels' => $this->labels
|
||||
'data' => $this->data, 'colors' => $this->colors
|
||||
));
|
||||
|
||||
try {
|
||||
$png = $pie->toPng($this->width, $this->height);
|
||||
$png = $pie->toPng($this->size, $this->size);
|
||||
return '<img class="inlinepie" src="data:image/png;base64,' . base64_encode($png) . '" />';
|
||||
} catch (IcingaException $_) {
|
||||
return '';
|
||||
|
@ -394,17 +211,17 @@ EOD;
|
|||
}
|
||||
|
||||
$template = $this->template;
|
||||
// TODO: Check whether we are XHR and don't send
|
||||
$template = str_replace('{noscript}', $this->noscript, $template);
|
||||
$template = str_replace('{url}', $this->url, $template);
|
||||
$template = str_replace('{class}', $this->class, $template);
|
||||
|
||||
// style
|
||||
$template = str_replace('{width}', $this->width, $template);
|
||||
$template = str_replace('{height}', $this->height, $template);
|
||||
$template = str_replace('{title}', htmlspecialchars($this->title), $template);
|
||||
$template = str_replace('{style}', $this->style, $template);
|
||||
$template = str_replace('{size}',
|
||||
isset($this->size) ? 'sparkWidth="' . $this->size . '" sparkHeight="' . $this->size . '" ' : '', $template);
|
||||
$template = str_replace('{title}', $this->title, $template);
|
||||
|
||||
$template = str_replace('{colors}', implode(',', $this->colors), $template);
|
||||
$template = str_replace('{borderWidth}', $this->borderWidth, $template);
|
||||
$template = str_replace('{borderColor}', $this->borderColor, $template);
|
||||
$template = str_replace('{hideEmptyLabel}', $this->hideEmptyLabel ? 'true' : 'false', $template);
|
||||
|
||||
// Locale-ignorant string cast. Please. Do. NOT. Remove. This. Again.
|
||||
// Problem is that implode respects locales when casting floats. This means
|
||||
|
@ -414,38 +231,7 @@ EOD;
|
|||
$data[] = sprintf('%F', $dat);
|
||||
}
|
||||
|
||||
// values
|
||||
$formatted = array();
|
||||
foreach ($this->data as $key => $value) {
|
||||
$formatted[$key] = $this->formatValue($value);
|
||||
}
|
||||
$template = str_replace('{data}', htmlspecialchars(implode(',', $data)), $template);
|
||||
$template = str_replace('{formatted}', htmlspecialchars(implode('|', $formatted)), $template);
|
||||
$template = str_replace('{labels}', htmlspecialchars($this->createLabelString()), $template);
|
||||
$template = str_replace('{tooltipFormat}', $this->tooltipFormat, $template);
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given value depending on the current value of numberFormat
|
||||
*
|
||||
* @param float $value The value to format
|
||||
*
|
||||
* @return string The formatted value
|
||||
*/
|
||||
private function formatValue($value)
|
||||
{
|
||||
if ($this->format === self::NUMBER_FORMAT_NONE) {
|
||||
return (string)$value;
|
||||
} elseif ($this->format === self::NUMBER_FORMAT_BYTES) {
|
||||
return Format::bytes($value);
|
||||
} elseif ($this->format === self::NUMBER_FORMAT_TIME) {
|
||||
return Format::duration($value);
|
||||
} elseif ($this->format === self::NUMBER_FORMAT_RATIO) {
|
||||
return $value;
|
||||
} else {
|
||||
Logger::warning('Unknown format string "' . $this->format . '" for InlinePie, value not formatted.');
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace Icinga\Web\Widget\Tabextension;
|
||||
|
||||
use Icinga\Application\Platform;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\Widget\Tab;
|
||||
use Icinga\Web\Widget\Tabs;
|
||||
|
@ -28,35 +29,6 @@ class OutputFormat implements Tabextension
|
|||
*/
|
||||
const TYPE_CSV = 'csv';
|
||||
|
||||
/**
|
||||
* An array containing the tab definitions for all supported types
|
||||
*
|
||||
* Using array_keys on this array or isset allows to check whether a
|
||||
* requested type is supported
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $supportedTypes = array(
|
||||
self::TYPE_PDF => array(
|
||||
'name' => 'pdf',
|
||||
'title' => 'PDF',
|
||||
'icon' => 'file-pdf',
|
||||
'urlParams' => array('format' => 'pdf'),
|
||||
),
|
||||
self::TYPE_CSV => array(
|
||||
'name' => 'csv',
|
||||
'title' => 'CSV',
|
||||
'icon' => 'file-excel',
|
||||
'urlParams' => array('format' => 'csv')
|
||||
),
|
||||
self::TYPE_JSON => array(
|
||||
'name' => 'json',
|
||||
'title' => 'JSON',
|
||||
'icon' => 'img/icons/json.png',
|
||||
'urlParams' => array('format' => 'json')
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* An array of tabs to be added to the dropdown area
|
||||
*
|
||||
|
@ -74,7 +46,7 @@ class OutputFormat implements Tabextension
|
|||
*/
|
||||
public function __construct(array $disabled = array())
|
||||
{
|
||||
foreach ($this->supportedTypes as $type => $tabConfig) {
|
||||
foreach ($this->getSupportedTypes() as $type => $tabConfig) {
|
||||
if (!in_array($type, $disabled)) {
|
||||
$tabConfig['url'] = Url::fromRequest();
|
||||
$tabConfig['tagParams'] = array(
|
||||
|
@ -98,4 +70,44 @@ class OutputFormat implements Tabextension
|
|||
$tabs->addAsDropdown($tab->getName(), $tab);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array containing the tab definitions for all supported types
|
||||
*
|
||||
* Using array_keys on this array or isset allows to check whether a
|
||||
* requested type is supported
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSupportedTypes()
|
||||
{
|
||||
$supportedTypes = array();
|
||||
|
||||
if (Platform::extensionLoaded('gd')) {
|
||||
$supportedTypes[self::TYPE_PDF] = array(
|
||||
'name' => 'pdf',
|
||||
'title' => 'PDF',
|
||||
'icon' => 'file-pdf',
|
||||
'urlParams' => array('format' => 'pdf'),
|
||||
);
|
||||
}
|
||||
|
||||
$supportedTypes[self::TYPE_CSV] = array(
|
||||
'name' => 'csv',
|
||||
'title' => 'CSV',
|
||||
'icon' => 'file-excel',
|
||||
'urlParams' => array('format' => 'csv')
|
||||
);
|
||||
|
||||
if (Platform::extensionLoaded('json')) {
|
||||
$supportedTypes[self::TYPE_JSON] = array(
|
||||
'name' => 'json',
|
||||
'title' => 'JSON',
|
||||
'icon' => 'img/icons/json.png',
|
||||
'urlParams' => array('format' => 'json')
|
||||
);
|
||||
}
|
||||
|
||||
return $supportedTypes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,3 +4,4 @@ DESTINATION=.
|
|||
wget -O ${FILENAME}.tar.gz https://github.com/erusev/parsedown/archive/${RELEASE}.tar.gz
|
||||
tar xfz ${FILENAME}.tar.gz -C $DESTINATION/ --strip-components 1 $FILENAME/Parsedown.php $FILENAME/LICENSE.txt
|
||||
chmod 644 $DESTINATION/Parsedown.php
|
||||
mv LICENSE.txt LICENSE
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
curl https://codeload.github.com/dompdf/dompdf/tar.gz/v0.6.1 -o dompdf-0.6.1.tar.gz
|
||||
tar xzf dompdf-0.6.1.tar.gz --strip-components 1 dompdf-0.6.1/{include/*.php,lib,dompdf*.php,LICENSE.LGPL}
|
||||
rm dompdf-0.6.1.tar.gz
|
||||
mv LICENSE.LGPL LICENSE
|
||||
|
||||
curl https://codeload.github.com/PhenX/php-font-lib/tar.gz/0.3.1 -o php-font-lib-0.3.1.tar.gz
|
||||
mkdir lib/php-font-lib/classes
|
||||
|
|
|
@ -8,12 +8,36 @@ use Icinga\Module\Doc\DocController;
|
|||
|
||||
class Doc_IcingawebController extends DocController
|
||||
{
|
||||
/**
|
||||
* Get the path to Icinga Web 2's documentation
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Zend_Controller_Action_Exception If Icinga Web 2's documentation is not available
|
||||
*/
|
||||
protected function getPath()
|
||||
{
|
||||
$path = Icinga::app()->getBaseDir('doc');
|
||||
if (is_dir($path)) {
|
||||
return $path;
|
||||
}
|
||||
if (($path = $this->Config()->get('documentation', 'icingaweb2')) !== null) {
|
||||
if (is_dir($path)) {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
$this->translate('Documentation for Icinga Web 2 is not available'),
|
||||
404
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* View the toc of Icinga Web 2's documentation
|
||||
*/
|
||||
public function tocAction()
|
||||
{
|
||||
return $this->renderToc(Icinga::app()->getApplicationDir('/../doc'), 'Icinga Web 2', 'doc/icingaweb/chapter');
|
||||
$this->renderToc($this->getPath(), 'Icinga Web 2', 'doc/icingaweb/chapter');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,12 +50,12 @@ class Doc_IcingawebController extends DocController
|
|||
$chapterId = $this->getParam('chapterId');
|
||||
if ($chapterId === null) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
$this->translate('Missing parameter \'chapterId\''),
|
||||
sprintf($this->translate('Missing parameter \'%s\''), 'chapterId'),
|
||||
404
|
||||
);
|
||||
}
|
||||
return $this->renderChapter(
|
||||
Icinga::app()->getApplicationDir('/../doc'),
|
||||
$this->renderChapter(
|
||||
$this->getPath(),
|
||||
$chapterId,
|
||||
'doc/icingaweb/toc',
|
||||
'doc/icingaweb/chapter'
|
||||
|
@ -43,6 +67,6 @@ class Doc_IcingawebController extends DocController
|
|||
*/
|
||||
public function pdfAction()
|
||||
{
|
||||
return $this->renderPdf(Icinga::app()->getApplicationDir('/../doc'), 'Icinga Web 2', 'doc/icingaweb/chapter');
|
||||
$this->renderPdf($this->getPath(), 'Icinga Web 2', 'doc/icingaweb/chapter');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,40 @@ use Icinga\Module\Doc\Exception\DocException;
|
|||
|
||||
class Doc_ModuleController extends DocController
|
||||
{
|
||||
/**
|
||||
* Get the path to a module documentation
|
||||
*
|
||||
* @param string $module The name of the module
|
||||
* @param string $default The default path
|
||||
* @param bool $suppressErrors Whether to not throw an exception if the module documentation is not
|
||||
* available
|
||||
*
|
||||
* @return string|null Path to the documentation or null if the module documentation is not
|
||||
* available and errors are suppressed
|
||||
*
|
||||
* @throws Zend_Controller_Action_Exception If the module documentation is not available and errors are not
|
||||
* suppressed
|
||||
*/
|
||||
protected function getPath($module, $default, $suppressErrors = false)
|
||||
{
|
||||
if (is_dir($default)) {
|
||||
return $default;
|
||||
}
|
||||
if (($path = $this->Config()->get('documentation', 'modules')) !== null) {
|
||||
$path = str_replace('{module}', $module, $path);
|
||||
if (is_dir($path)) {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
if ($suppressErrors) {
|
||||
return null;
|
||||
}
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
sprintf($this->translate('Documentation for module \'%s\' is not available'), $module),
|
||||
404
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* List modules which are enabled and having the 'doc' directory
|
||||
*/
|
||||
|
@ -16,10 +50,10 @@ class Doc_ModuleController extends DocController
|
|||
{
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
$modules = array();
|
||||
foreach (Icinga::app()->getModuleManager()->listEnabledModules() as $enabledModule) {
|
||||
$docDir = $moduleManager->getModuleDir($enabledModule, '/doc');
|
||||
if (is_dir($docDir)) {
|
||||
$modules[] = $enabledModule;
|
||||
foreach (Icinga::app()->getModuleManager()->listEnabledModules() as $module) {
|
||||
$path = $this->getPath($module, $moduleManager->getModuleDir($module, '/doc'), true);
|
||||
if ($path !== null) {
|
||||
$modules[] = $module;
|
||||
}
|
||||
}
|
||||
$this->view->modules = $modules;
|
||||
|
@ -37,7 +71,7 @@ class Doc_ModuleController extends DocController
|
|||
{
|
||||
if (empty($moduleName)) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
$this->translate('Missing parameter \'moduleName\''),
|
||||
sprintf($this->translate('Missing parameter \'%s\''), 'moduleName'),
|
||||
404
|
||||
);
|
||||
}
|
||||
|
@ -63,16 +97,15 @@ class Doc_ModuleController extends DocController
|
|||
*/
|
||||
public function tocAction()
|
||||
{
|
||||
$moduleName = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($moduleName);
|
||||
$this->view->moduleName = $moduleName;
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
$module = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($module);
|
||||
$this->view->moduleName = $module;
|
||||
try {
|
||||
return $this->renderToc(
|
||||
$moduleManager->getModuleDir($moduleName, '/doc'),
|
||||
$moduleName,
|
||||
$this->renderToc(
|
||||
$this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
|
||||
$module,
|
||||
'doc/module/chapter',
|
||||
array('moduleName' => $moduleName)
|
||||
array('moduleName' => $module)
|
||||
);
|
||||
} catch (DocException $e) {
|
||||
throw new Zend_Controller_Action_Exception($e->getMessage(), 404);
|
||||
|
@ -88,24 +121,23 @@ class Doc_ModuleController extends DocController
|
|||
*/
|
||||
public function chapterAction()
|
||||
{
|
||||
$moduleName = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($moduleName);
|
||||
$module = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($module);
|
||||
$chapterId = $this->getParam('chapterId');
|
||||
if ($chapterId === null) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
$this->translate('Missing parameter \'chapterId\''),
|
||||
sprintf($this->translate('Missing parameter \'%s\''), 'chapterId'),
|
||||
404
|
||||
);
|
||||
}
|
||||
$this->view->moduleName = $moduleName;
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
$this->view->moduleName = $module;
|
||||
try {
|
||||
return $this->renderChapter(
|
||||
$moduleManager->getModuleDir($moduleName, '/doc'),
|
||||
$this->renderChapter(
|
||||
$this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
|
||||
$chapterId,
|
||||
$this->_helper->url->url(array('moduleName' => $moduleName), 'doc/module/toc'),
|
||||
$this->_helper->url->url(array('moduleName' => $module), 'doc/module/toc'),
|
||||
'doc/module/chapter',
|
||||
array('moduleName' => $moduleName)
|
||||
array('moduleName' => $module)
|
||||
);
|
||||
} catch (DocException $e) {
|
||||
throw new Zend_Controller_Action_Exception($e->getMessage(), 404);
|
||||
|
@ -119,14 +151,13 @@ class Doc_ModuleController extends DocController
|
|||
*/
|
||||
public function pdfAction()
|
||||
{
|
||||
$moduleName = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($moduleName);
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
return $this->renderPdf(
|
||||
$moduleManager->getModuleDir($moduleName, '/doc'),
|
||||
$moduleName,
|
||||
$module = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($module);
|
||||
$this->renderPdf(
|
||||
$this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
|
||||
$module,
|
||||
'doc/module/chapter',
|
||||
array('moduleName' => $moduleName)
|
||||
array('moduleName' => $module)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/* @var $this \Icinga\Application\Modules\Module */
|
||||
/** @type $this \Icinga\Application\Modules\Module */
|
||||
|
||||
$section = $this->menuSection($this->translate('Documentation'), array(
|
||||
'title' => 'Documentation',
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# <a id="module-documentation"></a> Writing Module Documentation
|
||||
|
||||

|
||||
|
||||
Icinga Web 2 is capable of viewing your module's documentation, if the documentation is written in
|
||||
[Markdown](http://en.wikipedia.org/wiki/Markdown). Please refer to
|
||||
[Markdown Syntax Documentation](http://daringfireball.net/projects/markdown/syntax) for Markdown's formatting syntax.
|
||||
|
||||
## <a id="location"></a> Where to Put Module Documentation?
|
||||
|
||||
By default, your module's Markdown documentation files must be placed in the `doc` directory beneath your module's root
|
||||
directory, e.g.:
|
||||
|
||||
example-module/doc
|
||||
|
||||
## <a id="chapters"></a> Chapters
|
||||
|
||||
Each Markdown documentation file represents a chapter of your module's documentation. The first found heading inside
|
||||
each file is the chapter's title. The order of chapters is based on the case insensitive "Natural Order" of your files'
|
||||
names. <dfn>Natural Order</dfn> means that the file names are ordered in the way which seems natural to humans.
|
||||
It is best practice to prefix Markdown documentation file names with numbers to ensure that they appear in the correct
|
||||
order, e.g.:
|
||||
|
||||
1-about.md
|
||||
2-installation.md
|
||||
3-configuration.md
|
||||
|
||||
## <a id="toc"></a> Table Of Contents
|
||||
|
||||
The table of contents for your module's documentation is auto-generated based on all found headings inside each
|
||||
Markdown documentation file.
|
||||
|
||||
## <a id="linking"></a> Linking Between Headings
|
||||
|
||||
For linking between headings, place an anchor where you want to link to, e.g.:
|
||||
|
||||
# <a id="heading"></a> Heading
|
||||
|
||||
Now you can reference the anchor either in the same or **in another** Markdown documentation file, e.g.:
|
||||
|
||||
This is a link to [Heading](#heading).
|
||||
|
||||
## <a id="images"></a> Including Images
|
||||
|
||||
Images must placed in the `img` directory beneath your module's `public` directory, e.g.:
|
||||
|
||||
example-module/public/img/doc
|
||||
|
||||
Module images can be accessed using the following URL:
|
||||
|
||||
{baseURL}/img/{moduleName}/{file} e.g. icingaweb/img/example-module/doc/example.png
|
||||
|
||||
Markdown's image syntax is very similar to Markdown's link syntax, but prefixed with an exclamation mark, e.g.:
|
||||
|
||||

|
||||
|
||||
URLs to images inside your Markdown documentation files must be specified without the base URL, e.g.:
|
||||
|
||||

|
|
@ -28,7 +28,7 @@ class DocController extends ModuleActionController
|
|||
$urlParams
|
||||
);
|
||||
$this->view->title = $chapterId;
|
||||
return $this->render('chapter', null, true);
|
||||
$this->render('chapter', null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,7 +46,7 @@ class DocController extends ModuleActionController
|
|||
$name = ucfirst($name);
|
||||
$this->view->docName = $name;
|
||||
$this->view->title = sprintf($this->translate('%s Documentation'), $name);
|
||||
return $this->render('toc', null, true);
|
||||
$this->render('toc', null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,6 +71,6 @@ class DocController extends ModuleActionController
|
|||
);
|
||||
$this->view->docName = $name;
|
||||
$this->_request->setParam('format', 'pdf');
|
||||
return $this->render('pdf', null, true);
|
||||
$this->render('pdf', null, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ use Countable;
|
|||
use IteratorAggregate;
|
||||
use RecursiveIteratorIterator;
|
||||
use RecursiveDirectoryIterator;
|
||||
use Icinga\File\NonEmptyFileIterator;
|
||||
use Icinga\File\FileExtensionFilterIterator;
|
||||
|
||||
/**
|
||||
* Iterator over non-empty Markdown files ordered by the case insensitive "natural order" of file names
|
||||
|
@ -29,12 +31,14 @@ class DocIterator implements Countable, IteratorAggregate
|
|||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$it = new RecursiveIteratorIterator(
|
||||
$it = new FileExtensionFilterIterator(
|
||||
new NonEmptyFileIterator(
|
||||
new MarkdownFileIterator(
|
||||
new RecursiveDirectoryIterator($path)
|
||||
new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($path),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
)
|
||||
)
|
||||
),
|
||||
'md'
|
||||
);
|
||||
// Unfortunately we have no chance to sort the iterator
|
||||
$fileInfo = iterator_to_array($it);
|
||||
|
|
|
@ -31,7 +31,7 @@ class DocParser
|
|||
/**
|
||||
* Create a new documentation parser for the given path
|
||||
*
|
||||
* @param string $path Path to the documentation
|
||||
* @param string $path Path to the documentation
|
||||
*
|
||||
* @throws DocException If the documentation directory does not exist
|
||||
* @throws NotReadableError If the documentation directory is not readable
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Doc;
|
||||
|
||||
use RecursiveFilterIterator;
|
||||
|
||||
/**
|
||||
* Recursive iterator over Markdown files
|
||||
*/
|
||||
class MarkdownFileIterator extends RecursiveFilterIterator
|
||||
{
|
||||
/**
|
||||
* Accept files with '.md' suffix
|
||||
*
|
||||
* @return bool Whether the current element of the iterator is acceptable
|
||||
* through this filter
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
$current = $this->getInnerIterator()->current();
|
||||
/* @var $current \SplFileInfo */
|
||||
if (! $current->isFile()) {
|
||||
return false;
|
||||
}
|
||||
$filename = $current->getFilename();
|
||||
$sfx = substr($filename, -3);
|
||||
return $sfx === false ? false : strtolower($sfx) === '.md';
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}
|
||||
|
||||
namespace Icinga\Module\Doc;
|
||||
|
||||
use RecursiveFilterIterator;
|
||||
|
||||
/**
|
||||
* Recursive iterator over non-empty files
|
||||
*/
|
||||
class NonEmptyFileIterator extends RecursiveFilterIterator
|
||||
{
|
||||
/**
|
||||
* Accept non-empty files
|
||||
*
|
||||
* @return bool Whether the current element of the iterator is acceptable
|
||||
* through this filter
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
$current = $this->getInnerIterator()->current();
|
||||
/* @var $current \SplFileInfo */
|
||||
if (! $current->isFile()
|
||||
|| $current->getSize() === 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
Module: doc
|
||||
Version: 2.0.0~alpha4
|
||||
Version: 2.0.0
|
||||
Description: Documentation module
|
||||
Extracts, shows and exports documentation for Icinga Web 2 and it's modules.
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -47,4 +47,3 @@ $this->addRoute('doc/module/chapter', $docModuleChapter);
|
|||
$this->addRoute('doc/icingaweb/chapter', $docIcingaWebChapter);
|
||||
$this->addRoute('doc/module/toc', $docModuleToc);
|
||||
$this->addRoute('doc/module/pdf', $docModulePdf);
|
||||
|
||||
|
|
|
@ -72,8 +72,10 @@ class Monitoring_HostsController extends Controller
|
|||
'host_obsessing'*/
|
||||
));
|
||||
$unhandledObjects = array();
|
||||
$unhandledFilterExpressions = array();
|
||||
$acknowledgedObjects = array();
|
||||
$objectsInDowntime = array();
|
||||
$downtimeFilterExpressions = array();
|
||||
$hostStates = array(
|
||||
Host::getStateText(Host::STATE_UP) => 0,
|
||||
Host::getStateText(Host::STATE_DOWN) => 0,
|
||||
|
@ -81,15 +83,17 @@ class Monitoring_HostsController extends Controller
|
|||
Host::getStateText(Host::STATE_PENDING) => 0,
|
||||
);
|
||||
foreach ($this->hostList as $host) {
|
||||
/** @var Service $host */
|
||||
/** @var Host $host */
|
||||
if ((bool) $host->problem === true && (bool) $host->handled === false) {
|
||||
$unhandledObjects[] = $host;
|
||||
$unhandledFilterExpressions[] = Filter::where('host', $host->getName());
|
||||
}
|
||||
if ((bool) $host->acknowledged === true) {
|
||||
$acknowledgedObjects[] = $host;
|
||||
}
|
||||
if ((bool) $host->in_downtime === true) {
|
||||
$objectsInDowntime[] = $host;
|
||||
$downtimeFilterExpressions[] = Filter::where('downtime_host', $host->getName());
|
||||
}
|
||||
++$hostStates[$host::getStateText($host->state)];
|
||||
}
|
||||
|
@ -108,16 +112,15 @@ class Monitoring_HostsController extends Controller
|
|||
$this->view->hostStates = $hostStates;
|
||||
$this->view->objects = $this->hostList;
|
||||
$this->view->unhandledObjects = $unhandledObjects;
|
||||
$this->view->acknowledgeUnhandledLink = Url::fromRequest()
|
||||
->setPath('monitoring/hosts/acknowledge-problem')
|
||||
->addParams(array('host_problem' => 1, 'host_handled' => 0));
|
||||
$this->view->downtimeUnhandledLink = Url::fromRequest()
|
||||
->setPath('monitoring/hosts/schedule-downtime')
|
||||
->addParams(array('host_problem' => 1, 'host_handled' => 0));
|
||||
$unhandledFilterQueryString = Filter::matchAny($unhandledFilterExpressions)->toQueryString();
|
||||
$this->view->acknowledgeUnhandledLink = Url::fromPath('monitoring/hosts/acknowledge-problem')
|
||||
->setQueryString($unhandledFilterQueryString);
|
||||
$this->view->downtimeUnhandledLink = Url::fromPath('monitoring/hosts/schedule-downtime')
|
||||
->setQueryString($unhandledFilterQueryString);
|
||||
$this->view->acknowledgedObjects = $acknowledgedObjects;
|
||||
$this->view->objectsInDowntime = $objectsInDowntime;
|
||||
$this->view->inDowntimeLink = Url::fromRequest()
|
||||
->setPath('monitoring/list/downtimes');
|
||||
$this->view->inDowntimeLink = Url::fromPath('monitoring/list/downtimes')
|
||||
->setQueryString(Filter::matchAny($downtimeFilterExpressions)->toQueryString());
|
||||
$this->view->havingCommentsLink = Url::fromRequest()
|
||||
->setPath('monitoring/list/comments');
|
||||
$this->view->hostStatesPieChart = $this->createPieChart(
|
||||
|
@ -131,9 +134,6 @@ class Monitoring_HostsController extends Controller
|
|||
{
|
||||
$chart = new InlinePie(array_values($states), $title, $colors);
|
||||
return $chart
|
||||
->setLabel(array_map('strtoupper', array_keys($states)))
|
||||
->setHeight(100)
|
||||
->setWidth(100)
|
||||
->setTitle($title);
|
||||
}
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ class Monitoring_MultiController extends Controller
|
|||
private function createPie($states, $colors, $title)
|
||||
{
|
||||
$chart = new InlinePie(array_values($states), $title, $colors);
|
||||
$chart->setLabel(array_keys($states))->setHeight(100)->setWidth(100);
|
||||
$chart->setLabel(array_keys($states))->setSize(100);
|
||||
$chart->setTitle($title);
|
||||
return $chart;
|
||||
}
|
||||
|
|
|
@ -74,8 +74,10 @@ class Monitoring_ServicesController extends Controller
|
|||
'service_obsessing'*/
|
||||
));
|
||||
$unhandledObjects = array();
|
||||
$unhandledFilterExpressions = array();
|
||||
$acknowledgedObjects = array();
|
||||
$objectsInDowntime = array();
|
||||
$downtimeFilterExpressions = array();
|
||||
$serviceStates = array(
|
||||
Service::getStateText(Service::STATE_OK) => 0,
|
||||
Service::getStateText(Service::STATE_WARNING) => 0,
|
||||
|
@ -94,12 +96,20 @@ class Monitoring_ServicesController extends Controller
|
|||
/** @var Service $service */
|
||||
if ((bool) $service->problem === true && (bool) $service->handled === false) {
|
||||
$unhandledObjects[] = $service;
|
||||
$unhandledFilterExpressions[] = Filter::matchAll(
|
||||
Filter::where('host', $service->getHost()->getName()),
|
||||
Filter::where('service', $service->getName())
|
||||
);
|
||||
}
|
||||
if ((bool) $service->acknowledged === true) {
|
||||
$acknowledgedObjects[] = $service;
|
||||
}
|
||||
if ((bool) $service->in_downtime === true) {
|
||||
$objectsInDowntime[] = $service;
|
||||
$downtimeFilterExpressions[] = Filter::matchAll(
|
||||
Filter::where('downtime_host', $service->getHost()->getName()),
|
||||
Filter::where('downtime_service', $service->getName())
|
||||
);
|
||||
}
|
||||
++$serviceStates[$service::getStateText($service->state)];
|
||||
if (! isset($knownHostStates[$service->getHost()->getName()])) {
|
||||
|
@ -125,16 +135,15 @@ class Monitoring_ServicesController extends Controller
|
|||
$this->view->serviceStates = $serviceStates;
|
||||
$this->view->objects = $this->serviceList;
|
||||
$this->view->unhandledObjects = $unhandledObjects;
|
||||
$this->view->acknowledgeUnhandledLink = Url::fromRequest()
|
||||
->setPath('monitoring/services/acknowledge-problem')
|
||||
->addParams(array('service_problem' => 1, 'service_handled' => 0));
|
||||
$this->view->downtimeUnhandledLink = Url::fromRequest()
|
||||
->setPath('monitoring/services/schedule-downtime')
|
||||
->addParams(array('service_problem' => 1, 'service_handled' => 0));
|
||||
$unhandledFilterQueryString = Filter::matchAny($unhandledFilterExpressions)->toQueryString();
|
||||
$this->view->acknowledgeUnhandledLink = Url::fromPath('monitoring/services/acknowledge-problem')
|
||||
->setQueryString($unhandledFilterQueryString);
|
||||
$this->view->downtimeUnhandledLink = Url::fromPath('monitoring/services/schedule-downtime')
|
||||
->setQueryString($unhandledFilterQueryString);
|
||||
$this->view->acknowledgedObjects = $acknowledgedObjects;
|
||||
$this->view->objectsInDowntime = $objectsInDowntime;
|
||||
$this->view->inDowntimeLink = Url::fromRequest()
|
||||
->setPath('monitoring/list/downtimes');
|
||||
$this->view->inDowntimeLink = Url::fromPath('monitoring/list/downtimes')
|
||||
->setQueryString(Filter::matchAny($downtimeFilterExpressions)->toQueryString());
|
||||
$this->view->havingCommentsLink = Url::fromRequest()
|
||||
->setPath('monitoring/list/comments');
|
||||
$this->view->serviceStatesPieChart = $this->createPieChart(
|
||||
|
@ -153,10 +162,10 @@ class Monitoring_ServicesController extends Controller
|
|||
{
|
||||
$chart = new InlinePie(array_values($states), $title, $colors);
|
||||
return $chart
|
||||
->setLabel(array_map('strtoupper', array_keys($states)))
|
||||
->setHeight(100)
|
||||
->setWidth(100)
|
||||
->setTitle($title);
|
||||
// ->setLabel(array_map('strtoupper', array_keys($states)))
|
||||
->setSize(50)
|
||||
->setTitle($title)
|
||||
->setSparklineClass('sparkline-multi');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -73,9 +73,8 @@ class Monitoring_ShowController extends Controller
|
|||
public function historyAction()
|
||||
{
|
||||
$this->getTabs()->activate('history');
|
||||
//$this->view->object->populate();
|
||||
$this->view->object->fetchEventHistory();
|
||||
$this->view->history = $this->view->object->eventhistory->paginate($this->params->get('limit', 50));
|
||||
$this->view->history = $this->view->object->eventhistory->getQuery()->paginate($this->params->get('limit', 50));
|
||||
$this->handleFormatRequest($this->view->object->eventhistory);
|
||||
$this->fetchHostStats();
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ class AcknowledgeProblemCommandForm extends ObjectsCommandForm
|
|||
array(
|
||||
'decorators' => array(
|
||||
'FormElements',
|
||||
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group'))
|
||||
array('HtmlTag', array('tag' => 'div'))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -130,7 +130,7 @@ class ScheduleServiceDowntimeCommandForm extends ObjectsCommandForm
|
|||
array(
|
||||
'decorators' => array(
|
||||
'FormElements',
|
||||
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group'))
|
||||
array('HtmlTag', array('tag' => 'div'))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -169,7 +169,7 @@ class ScheduleServiceDowntimeCommandForm extends ObjectsCommandForm
|
|||
),
|
||||
'decorators' => array(
|
||||
'FormElements',
|
||||
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group')),
|
||||
array('HtmlTag', array('tag' => 'div')),
|
||||
array(
|
||||
'Description',
|
||||
array('tag' => 'span', 'class' => 'description', 'placement' => 'prepend')
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
namespace Icinga\Module\Monitoring\Forms\Config;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Web\Notification;
|
||||
|
||||
/**
|
||||
* Form class for creating/modifying monitoring backends
|
||||
|
@ -18,7 +18,7 @@ class BackendConfigForm extends ConfigForm
|
|||
/**
|
||||
* The available monitoring backend resources split by type
|
||||
*
|
||||
* @var array
|
||||
* @type array
|
||||
*/
|
||||
protected $resources;
|
||||
|
||||
|
@ -28,15 +28,15 @@ class BackendConfigForm extends ConfigForm
|
|||
public function init()
|
||||
{
|
||||
$this->setName('form_config_monitoring_backends');
|
||||
$this->setSubmitLabel(mt('monitoring', 'Save Changes'));
|
||||
$this->setSubmitLabel($this->translate('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resource configuration to use
|
||||
*
|
||||
* @param Config $resources The resource configuration
|
||||
* @param Config $resourceConfig The resource configuration
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*
|
||||
* @throws ConfigurationError In case there are no valid monitoring backend resources
|
||||
*/
|
||||
|
@ -50,7 +50,7 @@ class BackendConfigForm extends ConfigForm
|
|||
}
|
||||
|
||||
if (empty($resources)) {
|
||||
throw new ConfigurationError(mt('monitoring', 'Could not find any valid monitoring backend resources'));
|
||||
throw new ConfigurationError($this->translate('Could not find any valid monitoring backend resources'));
|
||||
}
|
||||
|
||||
$this->resources = $resources;
|
||||
|
@ -64,7 +64,7 @@ class BackendConfigForm extends ConfigForm
|
|||
*
|
||||
* @param array $values The values to extend the configuration with
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException In case the backend does already exist
|
||||
*/
|
||||
|
@ -72,9 +72,9 @@ class BackendConfigForm extends ConfigForm
|
|||
{
|
||||
$name = isset($values['name']) ? $values['name'] : '';
|
||||
if (! $name) {
|
||||
throw new InvalidArgumentException(mt('monitoring', 'Monitoring backend name missing'));
|
||||
throw new InvalidArgumentException($this->translate('Monitoring backend name missing'));
|
||||
} elseif ($this->config->hasSection($name)) {
|
||||
throw new InvalidArgumentException(mt('monitoring', 'Monitoring backend already exists'));
|
||||
throw new InvalidArgumentException($this->translate('Monitoring backend already exists'));
|
||||
}
|
||||
|
||||
unset($values['name']);
|
||||
|
@ -95,11 +95,11 @@ class BackendConfigForm extends ConfigForm
|
|||
public function edit($name, array $values)
|
||||
{
|
||||
if (! $name) {
|
||||
throw new InvalidArgumentException(mt('monitoring', 'Old monitoring backend name missing'));
|
||||
throw new InvalidArgumentException($this->translate('Old monitoring backend name missing'));
|
||||
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
|
||||
throw new InvalidArgumentException(mt('monitoring', 'New monitoring backend name missing'));
|
||||
throw new InvalidArgumentException($this->translate('New monitoring backend name missing'));
|
||||
} elseif (! $this->config->hasSection($name)) {
|
||||
throw new InvalidArgumentException(mt('monitoring', 'Unknown monitoring backend provided'));
|
||||
throw new InvalidArgumentException($this->translate('Unknown monitoring backend provided'));
|
||||
}
|
||||
|
||||
unset($values['name']);
|
||||
|
@ -119,9 +119,9 @@ class BackendConfigForm extends ConfigForm
|
|||
public function remove($name)
|
||||
{
|
||||
if (! $name) {
|
||||
throw new InvalidArgumentException(mt('monitoring', 'Monitoring backend name missing'));
|
||||
throw new InvalidArgumentException($this->translate('Monitoring backend name missing'));
|
||||
} elseif (! $this->config->hasSection($name)) {
|
||||
throw new InvalidArgumentException(mt('monitoring', 'Unknown monitoring backend provided'));
|
||||
throw new InvalidArgumentException($this->translate('Unknown monitoring backend provided'));
|
||||
}
|
||||
|
||||
$backendConfig = $this->config->getSection($name);
|
||||
|
@ -131,23 +131,21 @@ class BackendConfigForm extends ConfigForm
|
|||
|
||||
/**
|
||||
* Add or edit a monitoring backend and save the configuration
|
||||
*
|
||||
* @see Form::onSuccess()
|
||||
*/
|
||||
public function onSuccess()
|
||||
{
|
||||
$monitoringBackend = $this->request->getQuery('backend');
|
||||
try {
|
||||
if ($monitoringBackend === null) { // create new backend
|
||||
if ($monitoringBackend === null) { // Create new backend
|
||||
$this->add($this->getValues());
|
||||
$message = mt('monitoring', 'Monitoring backend "%s" has been successfully created');
|
||||
} else { // edit existing backend
|
||||
$message = $this->translate('Monitoring backend "%s" has been successfully created');
|
||||
} else { // Edit existing backend
|
||||
$this->edit($monitoringBackend, $this->getValues());
|
||||
$message = mt('monitoring', 'Monitoring backend "%s" has been successfully changed');
|
||||
$message = $this->translate('Monitoring backend "%s" has been successfully changed');
|
||||
}
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Notification::error($e->getMessage());
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->save()) {
|
||||
|
@ -160,18 +158,16 @@ class BackendConfigForm extends ConfigForm
|
|||
/**
|
||||
* Populate the form in case a monitoring backend is being edited
|
||||
*
|
||||
* @see Form::onRequest()
|
||||
*
|
||||
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
|
||||
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
|
||||
*/
|
||||
public function onRequest()
|
||||
{
|
||||
$monitoringBackend = $this->request->getQuery('backend');
|
||||
if ($monitoringBackend !== null) {
|
||||
if ($monitoringBackend === '') {
|
||||
throw new ConfigurationError(mt('monitoring', 'Monitoring backend name missing'));
|
||||
throw new ConfigurationError($this->translate('Monitoring backend name missing'));
|
||||
} elseif (! $this->config->hasSection($monitoringBackend)) {
|
||||
throw new ConfigurationError(mt('monitoring', 'Unknown monitoring backend provided'));
|
||||
throw new ConfigurationError($this->translate('Unknown monitoring backend provided'));
|
||||
}
|
||||
|
||||
$backendConfig = $this->config->getSection($monitoringBackend)->toArray();
|
||||
|
@ -181,7 +177,8 @@ class BackendConfigForm extends ConfigForm
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
* (non-PHPDoc)
|
||||
* @see Form::createElements() For the method documentation.
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
|
@ -200,7 +197,7 @@ class BackendConfigForm extends ConfigForm
|
|||
'disabled',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => mt('monitoring', 'Disable This Backend')
|
||||
'label' => $this->translate('Disable This Backend')
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
|
@ -208,8 +205,8 @@ class BackendConfigForm extends ConfigForm
|
|||
'name',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => mt('monitoring', 'Backend Name'),
|
||||
'description' => mt('monitoring', 'The identifier of this backend')
|
||||
'label' => $this->translate('Backend Name'),
|
||||
'description' => $this->translate('The identifier of this backend')
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
|
@ -218,8 +215,8 @@ class BackendConfigForm extends ConfigForm
|
|||
array(
|
||||
'required' => true,
|
||||
'autosubmit' => true,
|
||||
'label' => mt('monitoring', 'Backend Type'),
|
||||
'description' => mt('monitoring', 'The data source used for retrieving monitoring information'),
|
||||
'label' => $this->translate('Backend Type'),
|
||||
'description' => $this->translate('The data source used for retrieving monitoring information'),
|
||||
'multiOptions' => $resourceTypes,
|
||||
'value' => $resourceType
|
||||
)
|
||||
|
@ -230,8 +227,8 @@ class BackendConfigForm extends ConfigForm
|
|||
'resource',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => mt('monitoring', 'Resource'),
|
||||
'description' => mt('monitoring', 'The resource to use'),
|
||||
'label' => $this->translate('Resource'),
|
||||
'description' => $this->translate('The resource to use'),
|
||||
'multiOptions' => $this->resources[$resourceType],
|
||||
'autosubmit' => true
|
||||
)
|
||||
|
@ -253,8 +250,8 @@ class BackendConfigForm extends ConfigForm
|
|||
array(
|
||||
'value' => sprintf(
|
||||
'<a href="%s" data-base-target="_main">%s</a>',
|
||||
$this->getView()->href('/icingaweb/config/editresource', array('resource' => $resourceName)),
|
||||
mt('monitoring', 'Show resource configuration')
|
||||
$this->getView()->url('config/editresource', array('resource' => $resourceName)),
|
||||
$this->translate('Show resource configuration')
|
||||
),
|
||||
'escape' => false
|
||||
)
|
||||
|
|
|
@ -9,33 +9,36 @@ use Icinga\Module\Monitoring\Plugin\PerfdataSet;
|
|||
|
||||
class Zend_View_Helper_Perfdata extends Zend_View_Helper_Abstract
|
||||
{
|
||||
public function perfdata($perfdataStr, $compact = false)
|
||||
|
||||
/**
|
||||
* Display the given perfdata string to the user
|
||||
*
|
||||
* @param $perfdataStr The perfdata string
|
||||
* @param bool $compact Whether to display the perfdata in compact mode
|
||||
* @param $color The color indicating the perfdata state
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function perfdata($perfdataStr, $compact = false, $color = Perfdata::PERFDATA_DEFAULT)
|
||||
{
|
||||
$pset = PerfdataSet::fromString($perfdataStr)->asArray();
|
||||
$onlyPieChartData = array_filter($pset, function ($e) { return $e->getPercentage() > 0; });
|
||||
if ($compact) {
|
||||
$onlyPieChartData = array_slice($onlyPieChartData, 0, 5);
|
||||
} else {
|
||||
$nonPieChartData = array_filter($pset, function ($e) { return $e->getPercentage() == 0; });
|
||||
}
|
||||
$pieChartData = PerfdataSet::fromString($perfdataStr)->asArray();
|
||||
|
||||
$result = '';
|
||||
$table = array();
|
||||
foreach ($onlyPieChartData as $perfdata) {
|
||||
$pieChart = $this->createInlinePie($perfdata);
|
||||
if ($compact) {
|
||||
$result .= $pieChart->render();
|
||||
} else {
|
||||
if (! $perfdata->isPercentage()) {
|
||||
// TODO: Should we trust sprintf-style placeholders in perfdata titles?
|
||||
$pieChart->setTooltipFormat('{{label}}: {{formatted}} ({{percent}}%)');
|
||||
foreach ($pieChartData as $perfdata) {
|
||||
if ($perfdata->isVisualizable()) {
|
||||
$pieChart = $perfdata->asInlinePie($color);
|
||||
if ($compact) {
|
||||
$result .= $pieChart->render();
|
||||
} else {
|
||||
$table[] = '<tr><th>' . $pieChart->render()
|
||||
. htmlspecialchars($perfdata->getLabel())
|
||||
. '</th><td> '
|
||||
. htmlspecialchars($this->formatPerfdataValue($perfdata)) .
|
||||
' </td></tr>';
|
||||
}
|
||||
// $pieChart->setStyle('margin: 0.2em 0.5em 0.2em 0.5em;');
|
||||
$table[] = '<tr><th>' . $pieChart->render()
|
||||
. htmlspecialchars($perfdata->getLabel())
|
||||
. '</th><td> '
|
||||
. htmlspecialchars($this->formatPerfdataValue($perfdata)) .
|
||||
' </td></tr>';
|
||||
} else {
|
||||
$table[] = (string)$perfdata;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,32 +46,10 @@ class Zend_View_Helper_Perfdata extends Zend_View_Helper_Abstract
|
|||
return $result;
|
||||
} else {
|
||||
$pieCharts = empty($table) ? '' : '<table class="perfdata">' . implode("\n", $table) . '</table>';
|
||||
return $pieCharts . "\n" . implode("<br>\n", $nonPieChartData);
|
||||
return $pieCharts;
|
||||
}
|
||||
}
|
||||
|
||||
protected function calculatePieChartData(Perfdata $perfdata)
|
||||
{
|
||||
$rawValue = $perfdata->getValue();
|
||||
$minValue = $perfdata->getMinimumValue() !== null ? $perfdata->getMinimumValue() : 0;
|
||||
$maxValue = $perfdata->getMaximumValue();
|
||||
$usedValue = ($rawValue - $minValue);
|
||||
$unusedValue = ($maxValue - $minValue) - $usedValue;
|
||||
|
||||
$gray = $unusedValue;
|
||||
$green = $orange = $red = 0;
|
||||
// TODO(#6122): Add proper treshold parsing.
|
||||
if ($perfdata->getCriticalThreshold() && $perfdata->getValue() > $perfdata->getCriticalThreshold()) {
|
||||
$red = $usedValue;
|
||||
} elseif ($perfdata->getWarningThreshold() && $perfdata->getValue() > $perfdata->getWarningThreshold()) {
|
||||
$orange = $usedValue;
|
||||
} else {
|
||||
$green = $usedValue;
|
||||
}
|
||||
|
||||
return array($green, $orange, $red, $gray);
|
||||
}
|
||||
|
||||
protected function formatPerfdataValue(Perfdata $perfdata)
|
||||
{
|
||||
if ($perfdata->isBytes()) {
|
||||
|
@ -82,24 +63,4 @@ class Zend_View_Helper_Perfdata extends Zend_View_Helper_Abstract
|
|||
return $perfdata->getValue();
|
||||
}
|
||||
|
||||
protected function createInlinePie(Perfdata $perfdata)
|
||||
{
|
||||
$pieChart = new InlinePie($this->calculatePieChartData($perfdata), $perfdata->getLabel());
|
||||
$pieChart->setLabel(htmlspecialchars($perfdata->getLabel()));
|
||||
$pieChart->setHideEmptyLabel();
|
||||
|
||||
//$pieChart->setHeight(32)->setWidth(32);
|
||||
if ($perfdata->isBytes()) {
|
||||
$pieChart->setTooltipFormat('{{label}}: {{formatted}} ({{percent}}%)');
|
||||
$pieChart->setNumberFormat(InlinePie::NUMBER_FORMAT_BYTES);
|
||||
} else if ($perfdata->isSeconds()) {
|
||||
$pieChart->setTooltipFormat('{{label}}: {{formatted}} ({{percent}}%)');
|
||||
$pieChart->setNumberFormat(InlinePie::NUMBER_FORMAT_TIME);
|
||||
} else {
|
||||
$pieChart->setTooltipFormat('{{label}}: {{formatted}}%');
|
||||
$pieChart->setNumberFormat(InlinePie::NUMBER_FORMAT_RATIO);
|
||||
$pieChart->setHideEmptyLabel();
|
||||
}
|
||||
return $pieChart;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ use Icinga\Module\Monitoring\Object\Service;
|
|||
</td>
|
||||
<td>
|
||||
<?php if (isset($downtime->service)): ?>
|
||||
<a href="<?= $this->href('monitoring/service/show', array(
|
||||
<?= $this->icon('service'); ?> <a href="<?= $this->href('monitoring/service/show', array(
|
||||
'host' => $downtime->host,
|
||||
'service' => $downtime->service
|
||||
)); ?>">
|
||||
|
@ -63,7 +63,7 @@ use Icinga\Module\Monitoring\Object\Service;
|
|||
<?= $this->translate('on'); ?> <?= $downtime->host; ?>
|
||||
</small>
|
||||
<?php else: ?>
|
||||
<a href="<?= $this->href('monitoring/host/show', array(
|
||||
<?= $this->icon('host'); ?> <a href="<?= $this->href('monitoring/host/show', array(
|
||||
'host' => $downtime->host
|
||||
)); ?>">
|
||||
<?= $downtime->host; ?>
|
||||
|
@ -76,7 +76,9 @@ use Icinga\Module\Monitoring\Object\Service;
|
|||
<?php if ($downtime->is_flexible): ?>
|
||||
<?php if ($downtime->is_in_effect): ?>
|
||||
<?= sprintf(
|
||||
$this->translate('This flexible downtime was started on %s at %s and lasts for %s until %s at %s.'),
|
||||
isset($downtime->service)
|
||||
? $this->translate('This flexible service downtime was started on %s at %s and lasts for %s until %s at %s.')
|
||||
: $this->translate('This flexible host downtime was started on %s at %s and lasts for %s until %s at %s.'),
|
||||
date('d.m.y', $downtime->start),
|
||||
date('H:i', $downtime->start),
|
||||
$this->format()->duration($downtime->duration),
|
||||
|
@ -85,7 +87,9 @@ use Icinga\Module\Monitoring\Object\Service;
|
|||
); ?>
|
||||
<?php else: ?>
|
||||
<?= sprintf(
|
||||
$this->translate('This flexible downtime has been scheduled to start between %s - %s and to last for %s.'),
|
||||
isset($downtime->service)
|
||||
? $this->translate('This flexible service downtime has been scheduled to start between %s - %s and to last for %s.')
|
||||
: $this->translate('This flexible host downtime has been scheduled to start between %s - %s and to last for %s.'),
|
||||
date('d.m.y H:i', $downtime->scheduled_start),
|
||||
date('d.m.y H:i', $downtime->scheduled_end),
|
||||
$this->format()->duration($downtime->duration)
|
||||
|
@ -94,7 +98,9 @@ use Icinga\Module\Monitoring\Object\Service;
|
|||
<?php else: ?>
|
||||
<?php if ($downtime->is_in_effect): ?>
|
||||
<?= sprintf(
|
||||
$this->translate('This fixed downtime was started on %s at %s and expires on %s at %s.'),
|
||||
isset($downtime->service)
|
||||
? $this->translate('This fixed service downtime was started on %s at %s and expires on %s at %s.')
|
||||
: $this->translate('This fixed host downtime was started on %s at %s and expires on %s at %s.'),
|
||||
date('d.m.y', $downtime->start),
|
||||
date('H:i', $downtime->start),
|
||||
date('d.m.y', $downtime->end),
|
||||
|
@ -102,7 +108,9 @@ use Icinga\Module\Monitoring\Object\Service;
|
|||
); ?>
|
||||
<?php else: ?>
|
||||
<?= sprintf(
|
||||
$this->translate('This fixed downtime has been scheduled to start on %s at %s and to end on %s at %s.'),
|
||||
isset($downtime->service)
|
||||
? $this->translate('This fixed service downtime has been scheduled to start on %s at %s and to end on %s at %s.')
|
||||
: $this->translate('This fixed host downtime has been scheduled to start on %s at %s and to end on %s at %s.'),
|
||||
date('d.m.y', $downtime->scheduled_start),
|
||||
date('H:i', $downtime->scheduled_start),
|
||||
date('d.m.y', $downtime->scheduled_end),
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
</td>
|
||||
<?php endif ?>
|
||||
<td class="groupname">
|
||||
<a href="<?= $this->href('monitoring/list/services', array('hostgroup' => $h->hostgroup)); ?>">
|
||||
<a href="<?= $this->href('monitoring/list/hosts', array('hostgroup' => $h->hostgroup)); ?>">
|
||||
<?= $h->hostgroup; ?>
|
||||
</a>
|
||||
</td>
|
||||
|
|
|
@ -108,10 +108,9 @@ if ($hosts->count() === 0) {
|
|||
$host->host_unhandled_services),
|
||||
'monitoring/show/services',
|
||||
array(
|
||||
'host' => $host->host_name,
|
||||
'service_problem' => 1,
|
||||
'service_acknowledged' => 0,
|
||||
'service_in_downtime' => 0
|
||||
'host' => $host->host_name,
|
||||
'service_problem' => 1,
|
||||
'service_handled' => 0
|
||||
),
|
||||
array('style' => 'font-weight: normal')
|
||||
) ?>)</span>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
use Icinga\Module\Monitoring\Object\Host;
|
||||
use Icinga\Module\Monitoring\Object\Service;
|
||||
use Icinga\Module\Monitoring\Plugin\Perfdata;
|
||||
|
||||
$helper = $this->getHelper('MonitoringState');
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ if (empty($object->hostgroups)) return;
|
|||
|
||||
$list = array();
|
||||
foreach ($object->hostgroups as $name => $alias) {
|
||||
$list[] = $this->qlink($alias, 'monitoring/list/services', array(
|
||||
$list[] = $this->qlink($alias, 'monitoring/list/hosts', array(
|
||||
'hostgroup' => $name
|
||||
));
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/** @var $this \Icinga\Application\Modules\Module */
|
||||
/** @type $this \Icinga\Application\Modules\Module */
|
||||
|
||||
$this->providePermission(
|
||||
'monitoring/command/*',
|
||||
|
|
|
@ -518,12 +518,14 @@ class StatusQuery extends IdoQuery
|
|||
protected function joinServiceproblemsummary()
|
||||
{
|
||||
$sub = new Zend_Db_Expr('(SELECT'
|
||||
. ' SUM(CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth) > 0 THEN 0 ELSE 1 END) AS unhandled_services_count,'
|
||||
. ' SUM(CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END) AS handled_services_count,'
|
||||
. ' SUM(CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 0 ELSE 1 END) AS unhandled_services_count,'
|
||||
. ' SUM(CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 1 ELSE 0 END) AS handled_services_count,'
|
||||
. ' s.host_object_id FROM icinga_servicestatus ss'
|
||||
. ' JOIN icinga_services s'
|
||||
. ' ON s.service_object_id = ss.service_object_id'
|
||||
. ' AND ss.current_state > 0'
|
||||
. ' JOIN icinga_hoststatus hs'
|
||||
. ' ON hs.host_object_id = s.host_object_id'
|
||||
. ' GROUP BY s.host_object_id)');
|
||||
$this->select->joinLeft(
|
||||
array('sps' => $sub),
|
||||
|
|
|
@ -30,7 +30,7 @@ class IcingaCommandFileCommandRenderer implements IcingaCommandRendererInterface
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function escape($commandString)
|
||||
protected function escape($commandString)
|
||||
{
|
||||
return str_replace(array("\r", "\n"), array('\r', '\n'), $commandString);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class IcingaCommandFileCommandRenderer implements IcingaCommandRendererInterface
|
|||
if ($now === null) {
|
||||
$now = time();
|
||||
}
|
||||
return sprintf('[%u] %s', $now, $this->$renderMethod($command));
|
||||
return sprintf('[%u] %s', $now, $this->escape($this->$renderMethod($command)));
|
||||
}
|
||||
|
||||
public function renderAddComment(AddCommentCommand $command)
|
||||
|
|
|
@ -421,7 +421,7 @@ abstract class MonitoredObject
|
|||
if ($this->type === self::TYPE_SERVICE) {
|
||||
$eventHistory->where('service_description', $this->service_description);
|
||||
}
|
||||
$this->eventhistory = $eventHistory->getQuery();
|
||||
$this->eventhistory = $eventHistory;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,15 @@
|
|||
namespace Icinga\Module\Monitoring\Plugin;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Web\Widget\Chart\InlinePie;
|
||||
use Zend_Controller_Front;
|
||||
|
||||
class Perfdata
|
||||
{
|
||||
const PERFDATA_DEFAULT = 'green';
|
||||
const PERFDATA_RED = 'red';
|
||||
|
||||
/**
|
||||
* The performance data value being parsed
|
||||
*
|
||||
|
@ -159,6 +165,16 @@ class Perfdata
|
|||
return $this->unit === 'c';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether it is possible to display a visual representation
|
||||
*
|
||||
* @return bool True when the perfdata is visualizable
|
||||
*/
|
||||
public function isVisualizable()
|
||||
{
|
||||
return isset($this->minValue) && isset($this->maxValue) && isset($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this perfomance data's label
|
||||
*/
|
||||
|
@ -316,4 +332,50 @@ class Perfdata
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function calculatePieChartData( $color)
|
||||
{
|
||||
$rawValue = $this->getValue();
|
||||
$minValue = $this->getMinimumValue() !== null ? $this->getMinimumValue() : 0;
|
||||
$maxValue = $this->getMaximumValue();
|
||||
$usedValue = ($rawValue - $minValue);
|
||||
$unusedValue = ($maxValue - $minValue) - $usedValue;
|
||||
|
||||
$gray = $unusedValue;
|
||||
$green = $orange = $red = 0;
|
||||
|
||||
switch ($color) {
|
||||
case self::PERFDATA_DEFAULT:
|
||||
$green = $usedValue;
|
||||
break;
|
||||
|
||||
case self::PERFDATA_RED:
|
||||
$red = $usedValue;
|
||||
break;
|
||||
|
||||
case self::PERFDATA_ORANGE:
|
||||
$orange = $usedValue;
|
||||
break;
|
||||
}
|
||||
// TODO(#6122): Add proper treshold parsing.
|
||||
|
||||
return array($green, $orange, $red, $gray);
|
||||
}
|
||||
|
||||
|
||||
public function asInlinePie($color)
|
||||
{
|
||||
if (! $this->isVisualizable()) {
|
||||
throw new ProgrammingError('Cannot calculate piechart data for unvisualizable perfdata entry.');
|
||||
}
|
||||
|
||||
$data = $this->calculatePieChartData($color);
|
||||
$pieChart = new InlinePie($data, $this->getLabel() . ' ' . number_format($this->getPercentage(), 2) . '%');
|
||||
$pieChart->setSparklineClass('sparkline-perfdata');
|
||||
|
||||
if (Zend_Controller_Front::getInstance()->getRequest()->isXmlHttpRequest()) {
|
||||
$pieChart->disableNoScript();
|
||||
}
|
||||
return $pieChart;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,8 +223,6 @@ abstract class MonitoredObjectController extends Controller
|
|||
)
|
||||
);
|
||||
}
|
||||
$tabs
|
||||
->extend(new OutputFormat())
|
||||
->extend(new DashboardAction());
|
||||
$tabs->extend(new DashboardAction());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Tests\Icinga\Regression;
|
||||
|
||||
use Icinga\Test\BaseTestCase;
|
||||
use Icinga\Module\Monitoring\Command\IcingaCommand;
|
||||
use Icinga\Module\Monitoring\Command\Renderer\IcingaCommandFileCommandRenderer;
|
||||
|
||||
|
||||
/**
|
||||
* A command that has a hardcoded parameter with newlines
|
||||
*/
|
||||
class Bug6088Command extends IcingaCommand
|
||||
{
|
||||
public function getParameterWithCarriageReturnAndLineFeed()
|
||||
{
|
||||
return "foo\r\nbar";
|
||||
}
|
||||
|
||||
public function getBug()
|
||||
{
|
||||
return '6088';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A subclass of IcingaCommandFileCommandRenderer to utiliseIcingaCommandFileCommandRenderer
|
||||
* to render an instance of Bug6088Command
|
||||
*/
|
||||
class Bug6088CommandFileCommandRenderer extends IcingaCommandFileCommandRenderer
|
||||
{
|
||||
public function renderBug6088(Bug6088Command $command)
|
||||
{
|
||||
return 'SOLVE_BUG;' . $command->getBug() . ';' . $command->getParameterWithCarriageReturnAndLineFeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class Bug6088
|
||||
*
|
||||
* Multi-line comments don't work
|
||||
*
|
||||
* @see https://dev.icinga.org/issues/6088
|
||||
*/
|
||||
class Bug6088Test extends BaseTestCase
|
||||
{
|
||||
public function testWhetherCommandParametersWithMultipleLinesAreProperlyEscaped()
|
||||
{
|
||||
$command = new Bug6088Command();
|
||||
$renderer = new Bug6088CommandFileCommandRenderer();
|
||||
$commandString = $renderer->render($command);
|
||||
|
||||
$this->assertEquals(
|
||||
'SOLVE_BUG;6088;foo\r\nbar',
|
||||
substr($commandString, strpos($commandString, ' ') + 1),
|
||||
'Command parameters with multiple lines are not properly escaped'
|
||||
);
|
||||
}
|
||||
}
|
|
@ -112,7 +112,7 @@ class AuthBackendPage extends Form
|
|||
}
|
||||
|
||||
$this->addElements($backendForm->getElements());
|
||||
$this->getElement('name')->setValue('icingaweb');
|
||||
$this->getElement('name')->setValue('icingaweb2');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,9 +51,7 @@ $cliPath = realpath(Icinga::app()->getApplicationDir() . '/../bin/icingacli');
|
|||
</div>
|
||||
<p><?= mt('setup', 'In case the IcingaCLI is missing you can create the token manually:'); ?></p>
|
||||
<div class="code">
|
||||
<span>su <?= ($user = Platform::getPhpUser()) !== null ? $user : 'your_webserver_group'; ?> && mkdir -m 2770 <?= dirname($setupTokenPath); ?>;</span>
|
||||
<span>head -c 12 /dev/urandom | base64 | tee <?= $setupTokenPath; ?>;</span>
|
||||
<span>chmod 0660 <?= $setupTokenPath; ?>;</span>
|
||||
<span>su <?= ($user = Platform::getPhpUser()) !== null ? $user : 'your_webserver_user'; ?> -c "mkdir -m 2770 <?= dirname($setupTokenPath); ?>; head -c 12 /dev/urandom | base64 | tee <?= $setupTokenPath; ?>; chmod 0660 <?= $setupTokenPath; ?>;";</span>
|
||||
</div>
|
||||
<p><?= sprintf(
|
||||
mt('setup', 'Please see the %s for an extensive description on how to access and use this wizard.'),
|
||||
|
|
|
@ -38,10 +38,6 @@ class TokenValidator extends Zend_Validate_Abstract
|
|||
mt('setup', 'Cannot validate token, file "%s" is empty. Please define a token.'),
|
||||
$tokenPath
|
||||
),
|
||||
'TOKEN_FILE_PUBLIC' => sprintf(
|
||||
mt('setup', 'Cannot validate token, file "%s" must only be accessible by the webserver\'s user.'),
|
||||
$tokenPath
|
||||
),
|
||||
'TOKEN_INVALID' => mt('setup', 'Invalid token supplied.')
|
||||
);
|
||||
}
|
||||
|
@ -56,12 +52,6 @@ class TokenValidator extends Zend_Validate_Abstract
|
|||
*/
|
||||
public function isValid($value, $context = null)
|
||||
{
|
||||
$tokenStats = @stat($this->tokenPath);
|
||||
if (($tokenStats['mode'] & 4) === 4) {
|
||||
$this->_error('TOKEN_FILE_PUBLIC');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$file = new File($this->tokenPath);
|
||||
$expectedToken = trim($file->fgets());
|
||||
|
|
|
@ -9,6 +9,7 @@ use Icinga\Web\Form;
|
|||
use Icinga\Web\Wizard;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Platform;
|
||||
use Icinga\Module\Setup\Forms\ModulePage;
|
||||
use Icinga\Module\Setup\Forms\WelcomePage;
|
||||
|
@ -343,7 +344,7 @@ class WebWizard extends Wizard implements SetupWizard
|
|||
);
|
||||
}
|
||||
|
||||
$configDir = $this->getConfigDir();
|
||||
$configDir = Icinga::app()->getConfigDir();
|
||||
$setup->addStep(
|
||||
new MakeDirStep(
|
||||
array(
|
||||
|
@ -351,7 +352,7 @@ class WebWizard extends Wizard implements SetupWizard
|
|||
$configDir . '/preferences',
|
||||
$configDir . '/enabledModules'
|
||||
),
|
||||
0775
|
||||
2770
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -461,8 +462,8 @@ class WebWizard extends Wizard implements SetupWizard
|
|||
mt('setup', 'PHP Module: GD'),
|
||||
mt(
|
||||
'setup',
|
||||
'In case you want icons being exported to PDF as'
|
||||
. ' well, you\'ll need the GD extension for PHP.'
|
||||
'In case you want views being exported to PDF,'
|
||||
. ' you\'ll need the GD extension for PHP.'
|
||||
),
|
||||
Platform::extensionLoaded('gd'),
|
||||
Platform::extensionLoaded('gd') ? mt('setup', 'The PHP module GD is available') : (
|
||||
|
@ -528,12 +529,12 @@ class WebWizard extends Wizard implements SetupWizard
|
|||
)
|
||||
);
|
||||
|
||||
$configDir = $this->getConfigDir();
|
||||
$configDir = Icinga::app()->getConfigDir();
|
||||
$requirements->addMandatory(
|
||||
mt('setup', 'Writable Config Directory'),
|
||||
mt(
|
||||
'setup',
|
||||
'The Icinga Web 2 configuration directory defaults to "/etc/icingaweb", if' .
|
||||
'The Icinga Web 2 configuration directory defaults to "/etc/icingaweb2", if' .
|
||||
' not explicitly set in the environment variable "ICINGAWEB_CONFIGDIR".'
|
||||
),
|
||||
is_writable($configDir),
|
||||
|
@ -551,21 +552,4 @@ class WebWizard extends Wizard implements SetupWizard
|
|||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration directory of Icinga Web 2
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getConfigDir()
|
||||
{
|
||||
if (array_key_exists('ICINGAWEB_CONFIGDIR', $_SERVER)) {
|
||||
$configDir = $_SERVER['ICINGAWEB_CONFIGDIR'];
|
||||
} else {
|
||||
$configDir = '/etc/icingaweb';
|
||||
}
|
||||
|
||||
$canonical = realpath($configDir);
|
||||
return $canonical ? $canonical : $configDir;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ class GettextTranslationHelper
|
|||
*/
|
||||
public function __construct(ApplicationBootstrap $bootstrap, $locale)
|
||||
{
|
||||
$this->moduleMgr = $bootstrap->getModuleManager()->loadCoreModules()->loadEnabledModules();
|
||||
$this->moduleMgr = $bootstrap->getModuleManager()->loadEnabledModules();
|
||||
$this->appDir = $bootstrap->getApplicationDir();
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Alias /icingaweb "/usr/share/icingaweb2/public"
|
||||
Alias /icingaweb2 "/usr/share/icingaweb2/public"
|
||||
|
||||
<Directory "/usr/share/icingaweb2/public">
|
||||
Options SymLinksIfOwnerMatch
|
||||
|
@ -23,7 +23,7 @@ Alias /icingaweb "/usr/share/icingaweb2/public"
|
|||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteBase /icingaweb/
|
||||
RewriteBase /icingaweb2/
|
||||
RewriteCond %{REQUEST_FILENAME} -s [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -l [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
require_once '/usr/share/php/Icinga/Application/Cli.php';
|
||||
|
||||
Icinga\Application\Cli::start('/usr/share/icingaweb')->dispatch();
|
||||
Icinga\Application\Cli::start('/usr/share/icingaweb2')->dispatch();
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[documentation]
|
||||
icingaweb2 = /usr/share/doc/icingaweb2/markdown
|
||||
modules = /usr/share/doc/icingaweb2/modules/{module}/markdown
|
|
@ -195,7 +195,7 @@ tr.state.handled td.state {
|
|||
}
|
||||
|
||||
/* HOVER colors */
|
||||
tr.state:hover, tr[href]:hover {
|
||||
tr[href]:hover {
|
||||
color: black;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
|
|
@ -285,3 +285,10 @@ li li .badge {
|
|||
.widgetFilter li.active {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.sparkline {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
}
|
|
@ -32,6 +32,15 @@
|
|||
if ($outerMenu.size()) {
|
||||
$outerMenu.addClass('active');
|
||||
}
|
||||
|
||||
/*
|
||||
Recreate the html content of the menu item to force the browser to update the layout, or else
|
||||
the link would only be visible as active after another click or page reload in Gecko and WebKit.
|
||||
|
||||
fixes #7897
|
||||
*/
|
||||
$selectedMenu.html($selectedMenu.html());
|
||||
|
||||
} else {
|
||||
// store menu state
|
||||
var $menus = $('#menu li.active', el);
|
||||
|
|
|
@ -18,34 +18,33 @@
|
|||
|
||||
$('span.sparkline', el).each(function(i, element) {
|
||||
// read custom options
|
||||
var $spark = $(element);
|
||||
var labels = $spark.attr('labels').split('|');
|
||||
var formatted = $spark.attr('formatted').split('|');
|
||||
var tooltipChartTitle = $spark.attr('sparkTooltipChartTitle') || '';
|
||||
var format = $spark.attr('tooltipformat');
|
||||
var hideEmpty = $spark.attr('hideEmptyLabel') === 'true';
|
||||
$spark.sparkline(
|
||||
'html',
|
||||
{
|
||||
var $spark = $(element);
|
||||
var title = $spark.attr('title');
|
||||
|
||||
if ($spark.attr('labels')) {
|
||||
$spark.removeAttr('original-title');
|
||||
}
|
||||
|
||||
var options;
|
||||
if ($spark.hasClass('sparkline-perfdata')) {
|
||||
options = {
|
||||
enableTagOptions: true,
|
||||
tooltipFormatter: function (sparkline, options, fields) {
|
||||
var out = format;
|
||||
if (hideEmpty && fields.offset === 3) {
|
||||
return '';
|
||||
}
|
||||
var replace = {
|
||||
title: tooltipChartTitle,
|
||||
label: labels[fields.offset] ? labels[fields.offset] : fields.offset,
|
||||
formatted: formatted[fields.offset] ? formatted[fields.offset] : '',
|
||||
value: fields.value,
|
||||
percent: Math.round(fields.percent * 100) / 100
|
||||
};
|
||||
$.each(replace, function(key, value) {
|
||||
out = out.replace('{{' + key + '}}', value);
|
||||
});
|
||||
return out;
|
||||
}
|
||||
});
|
||||
width: 12,
|
||||
height: 12,
|
||||
title: title,
|
||||
disableTooltips: true
|
||||
};
|
||||
$spark.sparkline('html', options);
|
||||
} else if ($spark.hasClass('sparkline-multi')) {
|
||||
options = {
|
||||
width: 100,
|
||||
height: 100,
|
||||
title: title,
|
||||
enableTagOptions: true
|
||||
};
|
||||
$spark.sparkline('html', options);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue