From b89d61add35c7939cf2f1b46034bccb788c7a309 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Tue, 24 Sep 2013 15:26:10 +0200 Subject: [PATCH] Monitoring: Refactor data views (WIP) refs #4663 --- .../Application/ApplicationBootstrap.php | 4 +- .../Icinga/Application/Modules/Manager.php | 16 +- library/Icinga/Application/Web.php | 2 +- library/Icinga/Data/AbstractQuery.php | 1 - library/Icinga/Data/Db/Connection.php | 116 ++++++--- library/Icinga/Data/Db/Query.php | 2 +- library/Icinga/Data/ResourceFactory.php | 38 +++ .../controllers/ListController.php | 178 ++++++-------- .../controllers/ShowController.php | 230 +----------------- .../views/helpers/MonitoringFlags.php | 4 +- .../views/helpers/MonitoringProperties.php | 8 +- .../views/scripts/list/downtimes.phtml | 4 +- .../scripts/show/components/command.phtml | 18 +- .../scripts/show/components/comments.phtml | 26 +- .../scripts/show/components/contacts.phtml | 76 +++--- .../scripts/show/components/customvars.phtml | 4 +- .../scripts/show/components/downtime.phtml | 7 +- .../views/scripts/show/components/flags.phtml | 19 +- .../scripts/show/components/hostgroups.phtml | 18 ++ .../scripts/show/components/perfdata.phtml | 10 + .../show/components/pluginoutput.phtml | 9 + .../scripts/show/components/properties.phtml | 34 ++- .../show/components/servicegroups.phtml | 24 +- .../views/scripts/show/header.phtml | 39 ++- .../application/views/scripts/show/host.phtml | 102 +------- .../views/scripts/show/service.phtml | 103 +------- .../views/scripts/show/services.phtml | 2 - .../monitoring/library/Monitoring/Backend.php | 216 ++++++++-------- .../Monitoring/Backend/AbstractBackend.php | 4 +- .../library/Monitoring/Backend/Ido.php | 64 ----- .../Backend/Ido/Query/AbstractQuery.php | 11 +- .../Ido/Query/NotificationhistoryQuery.php | 4 +- .../library/Monitoring/Backend/Livestatus.php | 45 ---- .../library/Monitoring/Backend/Statusdat.php | 109 --------- .../library/Monitoring/DataView/DataView.php | 176 ++++++++++++++ .../library/Monitoring/DataView/Downtime.php | 50 ++++ .../DataView/HostAndServiceStatus.php | 131 ++++++++++ .../Monitoring/DataView/Notification.php | 41 ++++ .../Monitoring/Object/AbstractObject.php | 6 +- .../library/Monitoring/Object/Service.php | 3 +- 40 files changed, 910 insertions(+), 1044 deletions(-) create mode 100644 library/Icinga/Data/ResourceFactory.php create mode 100644 modules/monitoring/application/views/scripts/show/components/hostgroups.phtml create mode 100644 modules/monitoring/application/views/scripts/show/components/perfdata.phtml create mode 100644 modules/monitoring/application/views/scripts/show/components/pluginoutput.phtml delete mode 100644 modules/monitoring/application/views/scripts/show/services.phtml delete mode 100644 modules/monitoring/library/Monitoring/Backend/Ido.php delete mode 100644 modules/monitoring/library/Monitoring/Backend/Livestatus.php delete mode 100755 modules/monitoring/library/Monitoring/Backend/Statusdat.php create mode 100644 modules/monitoring/library/Monitoring/DataView/DataView.php create mode 100644 modules/monitoring/library/Monitoring/DataView/Downtime.php create mode 100644 modules/monitoring/library/Monitoring/DataView/HostAndServiceStatus.php create mode 100644 modules/monitoring/library/Monitoring/DataView/Notification.php diff --git a/library/Icinga/Application/ApplicationBootstrap.php b/library/Icinga/Application/ApplicationBootstrap.php index 8d325476a..3c6b7ca12 100755 --- a/library/Icinga/Application/ApplicationBootstrap.php +++ b/library/Icinga/Application/ApplicationBootstrap.php @@ -38,6 +38,7 @@ use \Icinga\Exception\ProgrammingError; use \Icinga\Application\DbAdapterFactory; use \Icinga\Exception\ConfigurationError; use \Icinga\Util\DateTimeFactory; +use Icinga\Data\ResourceFactory; /** * This class bootstraps a thin Icinga application layer @@ -388,10 +389,11 @@ abstract class ApplicationBootstrap * * @return self */ - protected function setupResourceFactories() + protected function setupResourceFactory() { $config = Config::app('resources'); DbAdapterFactory::setConfig($config); + ResourceFactory::setConfig($config); return $this; } diff --git a/library/Icinga/Application/Modules/Manager.php b/library/Icinga/Application/Modules/Manager.php index 8aef0119d..31727f9a3 100644 --- a/library/Icinga/Application/Modules/Manager.php +++ b/library/Icinga/Application/Modules/Manager.php @@ -28,14 +28,14 @@ namespace Icinga\Application\Modules; -use \Icinga\Application\ApplicationBootstrap; -use \Icinga\Application\Icinga; -use \Icinga\Application\Logger; -use \Icinga\Data\ArrayDatasource; -use \Icinga\Data\ArrayQuery; -use \Icinga\Exception\ConfigurationError; -use \Icinga\Exception\SystemPermissionException; -use \Icinga\Exception\ProgrammingError; +use Icinga\Application\ApplicationBootstrap; +use Icinga\Application\Icinga; +use Icinga\Application\Logger; +use Icinga\Data\DataArray\Datasource as ArrayDatasource; +use Icinga\Data\DataArray\Query as ArrayQuery; +use Icinga\Exception\ConfigurationError; +use Icinga\Exception\SystemPermissionException; +use Icinga\Exception\ProgrammingError; /** * Module manager that handles detecting, enabling and disabling of modules diff --git a/library/Icinga/Application/Web.php b/library/Icinga/Application/Web.php index a1b5647e4..f7b20318b 100644 --- a/library/Icinga/Application/Web.php +++ b/library/Icinga/Application/Web.php @@ -103,7 +103,7 @@ class Web extends ApplicationBootstrap { return $this->setupConfig() ->setupErrorHandling() - ->setupResourceFactories() + ->setupResourceFactory() ->setupUser() ->setupTimezone() ->setupRequest() diff --git a/library/Icinga/Data/AbstractQuery.php b/library/Icinga/Data/AbstractQuery.php index a961d7804..0baf30ddb 100644 --- a/library/Icinga/Data/AbstractQuery.php +++ b/library/Icinga/Data/AbstractQuery.php @@ -175,7 +175,6 @@ abstract class AbstractQuery implements QueryInterface $dir = self::SORT_ASC; } } - $this->order_columns[] = array($col, $dir); return $this; } diff --git a/library/Icinga/Data/Db/Connection.php b/library/Icinga/Data/Db/Connection.php index 7abe5b0b4..9c6aff566 100644 --- a/library/Icinga/Data/Db/Connection.php +++ b/library/Icinga/Data/Db/Connection.php @@ -28,14 +28,11 @@ namespace Icinga\Data\Db; -use \PDO; -use \Zend_Config; -use \Zend_Db; -use \Zend_Db_Adapter_Abstract; -use \Icinga\Application\DbAdapterFactory; -use \Icinga\Data\DatasourceInterface; -use \Icinga\Exception\ConfigurationError; -use \Icinga\Application\Logger; +use PDO; +use Zend_Config; +use Zend_Db; +use Icinga\Data\DatasourceInterface; +use Icinga\Exception\ConfigurationError; /** * Encapsulate database connections and query creation @@ -43,25 +40,33 @@ use \Icinga\Application\Logger; class Connection implements DatasourceInterface { /** - * Database connection - * - * @var Zend_Db_Adapter_Abstract - */ - protected $db; - - /** - * Backend configuration + * Connection config * * @var Zend_Config */ - protected $config; + private $config; /** * Database type * * @var string */ - protected $dbType; + private $dbType; + + private $conn; + + private $tablePrefix = ''; + + private static $genericAdapterOptions = array( + Zend_Db::AUTO_QUOTE_IDENTIFIERS => false, + Zend_Db::CASE_FOLDING => Zend_Db::CASE_LOWER + ); + + private static $driverOptions = array( + PDO::ATTR_TIMEOUT => 2, + PDO::ATTR_CASE => PDO::CASE_LOWER, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION + ); /** * Create a new connection object @@ -109,22 +114,69 @@ class Connection implements DatasourceInterface */ private function connect() { - $resourceName = $this->config->get('resource'); - $this->db = DbAdapterFactory::getDbAdapter($resourceName); - - if ($this->db->getConnection() instanceof PDO) { - $this->dbType = $this->db->getConnection()->getAttribute(PDO::ATTR_DRIVER_NAME); - } else { - $this->dbType = strtolower(get_class($this->db->getConnection())); + $genericAdapterOptions = self::$genericAdapterOptions; + $driverOptions = self::$driverOptions; + $adapterParamaters = array( + 'host' => $this->config->host, + 'username' => $this->config->username, + 'password' => $this->config->password, + 'dbname' => $this->config->dbname, + 'options' => & $genericAdapterOptions, + 'driver_options' => & $driverOptions + ); + $this->dbType = strtolower($this->config->get('db', 'mysql')); + switch ($this->dbType) { + case 'mysql': + $adapter = 'Pdo_Mysql'; + /* + * Set MySQL server SQL modes to behave as closely as possible to Oracle and PostgreSQL. Note that the + * ONLY_FULL_GROUP_BY mode is left on purpose because MySQL requires you to specify all non-aggregate columns + * in the group by list even if the query is grouped by the master table's primary key which is valid + * ANSI SQL though. Further in that case the query plan would suffer if you add more columns to the group by + * list. + */ + $driverOptions[PDO::MYSQL_ATTR_INIT_COMMAND] = + 'SET SESSION SQL_MODE=\'STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,' + . 'NO_AUTO_CREATE_USER,ANSI_QUOTES,PIPES_AS_CONCAT,NO_ENGINE_SUBSTITUTION\';'; + $adapterParamaters['port'] = $this->config->get('port', 3306); + break; + case 'pgsql': + $adapter = 'Pdo_Pgsql'; + $adapterParamaters['port'] = $this->config->get('port', 5432); + break; +// case 'oracle': +// if ($this->dbtype === 'oracle') { +// $attributes['persistent'] = true; +// } +// $this->db = ZfDb::factory($adapter, $attributes); +// if ($adapter === 'Oracle') { +// $this->db->setLobAsString(false); +// } +// break; + default: + throw new ConfigurationError( + sprintf( + 'Backend "%s" is not supported', $this->dbType + ) + ); } - $this->db->setFetchMode(Zend_Db::FETCH_OBJ); + $this->conn = Zend_Db::factory($adapter, $adapterParamaters); + $this->conn->setFetchMode(Zend_Db::FETCH_OBJ); + } - if ($this->dbType === null) { - Logger::warn('Could not determine database type'); - } + public function getConnection() + { + return $this->conn; + } - if ($this->dbType === 'oci') { - $this->dbType = 'oracle'; - } + public function getTablePrefix() + { + return $this->tablePrefix; + } + + public function setTablePrefix($prefix) + { + $this->tablePrefix = $prefix; + return $this; } } diff --git a/library/Icinga/Data/Db/Query.php b/library/Icinga/Data/Db/Query.php index 7867d4b1e..052ab2c1f 100644 --- a/library/Icinga/Data/Db/Query.php +++ b/library/Icinga/Data/Db/Query.php @@ -40,7 +40,7 @@ class Query extends AbstractQuery protected function init() { - $this->db = $this->ds->getConnection()->getDb(); + $this->db = $this->ds->getConnection(); $this->baseQuery = $this->db->select(); } diff --git a/library/Icinga/Data/ResourceFactory.php b/library/Icinga/Data/ResourceFactory.php new file mode 100644 index 000000000..217afb932 --- /dev/null +++ b/library/Icinga/Data/ResourceFactory.php @@ -0,0 +1,38 @@ +get($resourceName)) === null) { + throw new ConfigurationError('BLUBB?!'); + } + switch (strtolower($resourceConfig->type)) { + case 'db': + $resource = new DbConnection($resourceConfig); + break; + default: + throw new ConfigurationError('BLUBB2?!'); + + } + return $resource; + } +} diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php index dfa39d7c9..8199db163 100644 --- a/modules/monitoring/application/controllers/ListController.php +++ b/modules/monitoring/application/controllers/ListController.php @@ -18,6 +18,7 @@ * 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. * @@ -39,9 +40,10 @@ use \Icinga\Module\Monitoring\Backend; use \Icinga\Web\Widget\SortBox; use \Icinga\Application\Config as IcingaConfig; -/** - * Controller for listing views - */ +use Icinga\Module\Monitoring\DataView\Notification as NotificationView; +use Icinga\Module\Monitoring\DataView\Downtime as DowntimeView; +use Icinga\Module\Monitoring\DataView\HostAndServiceStatus as HostAndServiceStatusView; + class Monitoring_ListController extends ActionController { /** @@ -67,7 +69,7 @@ class Monitoring_ListController extends ActionController */ public function init() { - $this->backend = Backend::getInstance($this->_getParam('backend')); + $this->backend = Backend::createBackend($this->_getParam('backend')); $this->view->grapher = Hook::get('grapher'); $this->createTabs(); $this->view->activeRowHref = $this->getParam('detail'); @@ -88,10 +90,9 @@ class Monitoring_ListController extends ActionController */ public function hostsAction() { - Benchmark::measure("hostsAction::query()"); - $this->compactView = "hosts-compact"; - $this->view->hosts = $this->query( - 'status', + $this->compactView = 'hosts-compact'; + $query = HostAndServiceStatusView::fromRequest( + $this->_request, array( 'host_icon_image', 'host_name', @@ -112,7 +113,8 @@ class Monitoring_ListController extends ActionController 'host_notes_url', 'host_last_comment' ) - ); + )->getQuery(); + $this->view->hosts = $query->paginate(); $this->setupSortControl(array( 'host_last_check' => 'Last Host Check', 'host_severity' => 'Host Severity', @@ -121,6 +123,7 @@ class Monitoring_ListController extends ActionController 'host_address' => 'Address', 'host_state' => 'Hard State' )); + $this->handleFormatRequest($query); } /** @@ -128,36 +131,38 @@ class Monitoring_ListController extends ActionController */ public function servicesAction() { - $this->compactView = "services-compact"; - - $this->view->services = $this->query('status', array( - 'host_name', - 'host_state', - 'host_state_type', - 'host_last_state_change', - 'host_address', - 'host_handled', - 'service_description', - 'service_display_name', - 'service_state' => 'service_state', - 'service_in_downtime', - 'service_acknowledged', - 'service_handled', - 'service_output', - 'service_last_state_change' => 'service_last_state_change', - 'service_icon_image', - 'service_long_output', - 'service_is_flapping', - 'service_state_type', - 'service_handled', - 'service_severity', - 'service_last_check', - 'service_notifications_enabled', - 'service_action_url', - 'service_notes_url', - 'service_last_comment' - )); - + $this->compactView = 'services-compact'; + $query = HostAndServiceStatusView::fromRequest( + $this->_request, + array( + 'host_name', + 'host_state', + 'host_state_type', + 'host_last_state_change', + 'host_address', + 'host_handled', + 'service_description', + 'service_display_name', + 'service_state' => 'service_state', + 'service_in_downtime', + 'service_acknowledged', + 'service_handled', + 'service_output', + 'service_last_state_change' => 'service_last_state_change', + 'service_icon_image', + 'service_long_output', + 'service_is_flapping', + 'service_state_type', + 'service_handled', + 'service_severity', + 'service_last_check', + 'service_notifications_enabled', + 'service_action_url', + 'service_notes_url', + 'service_last_comment' + ) + )->getQuery(); + $this->view->services = $query->paginate(); $this->setupSortControl(array( 'service_last_check' => 'Last Service Check', 'service_severity' => 'Severity', @@ -169,7 +174,8 @@ class Monitoring_ListController extends ActionController 'host_name' => 'Host Name', 'host_address' => 'Host Address', 'host_last_check' => 'Last Host Check' - )); + )); + $this->handleFormatRequest($query); } /** @@ -177,24 +183,26 @@ class Monitoring_ListController extends ActionController */ public function downtimesAction() { - $this->setDefaultSortColumn('downtime_is_in_effect'); - $this->view->downtimes = $this->query('downtime', array( - 'host_name', - 'object_type', - 'service_description', - 'downtime_entry_time', - 'downtime_internal_downtime_id', - 'downtime_author_name', - 'downtime_comment_data', - 'downtime_duration', - 'downtime_scheduled_start_time', - 'downtime_scheduled_end_time', - 'downtime_is_fixed', - 'downtime_is_in_effect', - 'downtime_triggered_by_id', - 'downtime_trigger_time' - )); - + $query = DowntimeView::fromRequest( + $this->_request, + array( + 'host_name', + 'object_type', + 'service_description', + 'downtime_entry_time', + 'downtime_internal_downtime_id', + 'downtime_author_name', + 'downtime_comment_data', + 'downtime_duration', + 'downtime_scheduled_start_time', + 'downtime_scheduled_end_time', + 'downtime_is_fixed', + 'downtime_is_in_effect', + 'downtime_triggered_by_id', + 'downtime_trigger_time' + ) + )->getQuery(); + $this->view->downtimes = $query->paginate(); $this->setupSortControl(array( 'downtime_is_in_effect' => 'Is In Effect', 'object_type' => 'Service/Host', @@ -208,7 +216,8 @@ class Monitoring_ListController extends ActionController 'downtime_trigger_time' => 'Trigger Time', 'downtime_internal_downtime_id' => 'Downtime ID', 'downtime_duration' => 'Duration', - )); + )); + $this->handleFormatRequest($query); } /** @@ -216,9 +225,8 @@ class Monitoring_ListController extends ActionController */ public function notificationsAction() { - $this->setDefaultSortColumn('notification_start_time', 'DESC'); - $this->view->notifications = $this->query( - 'notification', + $query = NotificationView::fromRequest( + $this->_request, array( 'host_name', 'service_description', @@ -229,39 +237,12 @@ class Monitoring_ListController extends ActionController 'notification_information', 'notification_command' ) - ); + )->getQuery(); + $this->view->notifications = $query->paginate(); $this->setupSortControl(array( 'notification_start_time' => 'Notification Start' )); - } - - /** - * Create query - * - * @param string $view - * @param array $columns - * - * @return Query - */ - private function query($view, $columns) - { - $extra = preg_split( - '~,~', - $this->_getParam('extracolumns', ''), - -1, - PREG_SPLIT_NO_EMPTY - ); - if (empty($extra)) { - $cols = $columns; - } else { - $cols = array_merge($columns, $extra); - } - $this->view->extraColumns = $extra; - $query = $this->backend->select() - ->from($view, $cols) - ->applyRequest($this->_request); $this->handleFormatRequest($query); - return $query->paginate(); } /** @@ -278,7 +259,7 @@ class Monitoring_ListController extends ActionController if ($this->_getParam('format') === 'sql' && IcingaConfig::app()->global->get('environment', 'production') === 'development') { echo '
'
-                . htmlspecialchars(wordwrap($query->getQuery()->dump()))
+                . htmlspecialchars(wordwrap($query->dump()))
                 . '
'; exit; } @@ -296,19 +277,6 @@ class Monitoring_ListController extends ActionController } } - /** - * Set the default sort column for this action if none is provided - * - * @param string $column The column to use for sorting - * @param string $dir The direction ('ASC' or 'DESC') - */ - private function setDefaultSortColumn($column, $dir = 'DESC') - { - - $this->setParam('sort', $this->getParam('sort', $column)); - $this->setParam('dir', $this->getParam('dir', $dir)); - } - /** * Create a sort control box at the 'sortControl' view parameter * diff --git a/modules/monitoring/application/controllers/ShowController.php b/modules/monitoring/application/controllers/ShowController.php index 47cc83cf1..688f211a1 100644 --- a/modules/monitoring/application/controllers/ShowController.php +++ b/modules/monitoring/application/controllers/ShowController.php @@ -57,7 +57,7 @@ class Monitoring_ShowController extends ActionController { $host = $this->_getParam('host'); $service = $this->_getParam('service'); - $this->backend = Backend::getInstance($this->_getParam('backend')); + $this->backend = Backend::createBackend($this->_getParam('backend')); $object = null; // TODO: Do not allow wildcards in names! if ($host !== null) { @@ -70,13 +70,6 @@ class Monitoring_ShowController extends ActionController } } - $this->backend = Backend::getInstance($this->_getParam('backend')); - if ($service !== null && $service !== '*') { - $this->view->service = $this->backend->fetchService($host, $service, true); - } - if ($host !== null) { - $this->view->host = $this->backend->fetchHost($host, true); - } $this->view->compact = $this->_getParam('view') === 'compact'; if ($object === null) { // TODO: Notification, not found @@ -92,114 +85,7 @@ class Monitoring_ShowController extends ActionController */ public function serviceAction() { - Benchmark::measure('Entered service action'); - $this->view->active = 'service'; - - if ($grapher = Hook::get('grapher')) { - if ($grapher->hasGraph( - $this->view->service->host_name, - $this->view->service->service_description - ) - ) { - $this->view->preview_image = $grapher->getPreviewImage( - $this->view->service->host_name, - $this->view->service->service_description - ); - } - } - - $this->view->servicegroups = $this->backend->select() - ->from( - 'servicegroup', - array( - 'servicegroup_name', - 'servicegroup_alias' - ) - ) - ->where('host_name', $this->view->host->host_name) - ->where('service_description', $this->view->service->service_description) - - ->fetchPairs(); - - $this->view->contacts = $this->backend->select() - ->from( - 'contact', - array( - 'contact_name', - 'contact_alias', - 'contact_email', - 'contact_pager', - ) - ) - ->where('service_host_name', $this->view->host->host_name) - ->where('service_description', $this->view->service->service_description) - ->fetchAll(); - - $this->view->contactgroups = $this->backend->select() - ->from( - 'contactgroup', - array( - 'contactgroup_name', - 'contactgroup_alias', - ) - ) - ->where('service_host_name', $this->view->host->host_name) - ->where('service_description', $this->view->service->service_description) - ->fetchAll(); - - $this->view->comments = $this->backend->select() - ->from( - 'comment', - array( - 'comment_timestamp', - 'comment_author', - 'comment_data', - 'comment_type', - ) - ) - ->where('service_host_name', $this->view->host->host_name) - ->where('service_description', $this->view->service->service_description) - ->fetchAll(); - - $this->view->downtimes = $this->backend->select() - ->from( - 'downtime', - array( - 'host_name', - 'service_description', - 'downtime_type', - 'downtime_author_name', - 'downtime_comment_data', - 'downtime_is_fixed', - 'downtime_duration', - 'downtime_scheduled_start_time', - 'downtime_scheduled_end_time', - 'downtime_actual_start_time', - 'downtime_was_started', - 'downtime_is_in_effect', - 'downtime_internal_downtime_id' - ) - ) - ->where('host_name', $this->view->host->host_name) - ->where('service_description', $this->view->service->service_description) - ->where('object_type','service') - ->fetchAll(); - - $this->view->customvars = $this->backend->select() - ->from( - 'customvar', - array( - 'varname', - 'varvalue' - ) - ) - ->where('varname', '-*PW*,-*PASS*') - ->where('host_name', $this->view->host->host_name) - ->where('service_description', $this->view->service->service_description) - ->where('object_type', 'service') - ->fetchPairs(); - Benchmark::measure('Service action done'); - $object = $this->view->object->prefetch(); + $this->view->object->prefetch(); } /** @@ -207,97 +93,6 @@ class Monitoring_ShowController extends ActionController */ public function hostAction() { - $this->view->active = 'host'; - if ($grapher = Hook::get('grapher')) { - if ($grapher->hasGraph($this->view->host->host_name)) { - $this->view->preview_image = $grapher->getPreviewImage( - $this->view->host->host_name - ); - } - } - - $this->view->hostgroups = $this->backend->select() - ->from( - 'hostgroup', - array( - 'hostgroup_name', - 'hostgroup_alias' - ) - ) - ->where('host_name', $this->view->host->host_name) - ->fetchPairs(); - - $this->view->contacts = $this->backend->select() - ->from( - 'contact', - array( - 'contact_name', - 'contact_alias', - 'contact_email', - 'contact_pager', - ) - ) - ->where('host_name', $this->view->host->host_name) - ->fetchAll(); - - $this->view->contactgroups = $this->backend->select() - ->from( - 'contactgroup', - array( - 'contactgroup_name', - 'contactgroup_alias', - ) - ) - ->where('host_name', $this->view->host->host_name) - ->fetchAll(); - - $this->view->comments = $this->backend->select() - ->from( - 'comment', - array( - 'comment_timestamp', - 'comment_author', - 'comment_data', - 'comment_type', - ) - ) - ->where('host_name', $this->view->host->host_name) - ->fetchAll(); - - $this->view->downtimes = $this->backend->select() - ->from( - 'downtime', - array( - 'host_name', - 'downtime_type', - 'downtime_author_name', - 'downtime_comment_data', - 'downtime_is_fixed', - 'downtime_duration', - 'downtime_scheduled_start_time', - 'downtime_scheduled_end_time', - 'downtime_actual_start_time', - 'downtime_was_started', - 'downtime_is_in_effect', - 'downtime_internal_downtime_id' - ) - ) - ->where('host_name', $this->view->host->host_name) - ->where('object_type','host') - ->fetchAll(); - - $this->view->customvars = $this->backend->select() - ->from( - 'customvar', - array( - 'varname', - 'varvalue' - ) - ) - ->where('varname', '-*PW*,-*PASS*') - ->where('host_name', $this->view->host->host_name) - ->where('object_type', 'host') - ->fetchPairs(); $this->view->object->prefetch(); } @@ -333,27 +128,6 @@ class Monitoring_ShowController extends ActionController $this->view->preserve = $this->view->history->getAppliedFilter()->toParams(); } - /** - * Service overview - */ - public function servicesAction() - { - $this->_setParam('service', null); - // Ugly and slow: - $this->view->services = $this->view->action( - 'services', - 'list', - 'monitoring', - array( - 'host_name' => $this->view->host->host_name, - //'sort', 'service_description' - ) - ); - $this->view->services = $this->view->action('services', 'list', 'monitoring', array( - 'view' => 'compact' - )); - } - /** * Creating tabs for this controller * @return Tabs diff --git a/modules/monitoring/application/views/helpers/MonitoringFlags.php b/modules/monitoring/application/views/helpers/MonitoringFlags.php index ccecfa303..5e5f0851d 100644 --- a/modules/monitoring/application/views/helpers/MonitoringFlags.php +++ b/modules/monitoring/application/views/helpers/MonitoringFlags.php @@ -25,6 +25,8 @@ */ // {{{ICINGA_LICENSE_HEADER}}} +use Icinga\Module\Monitoring\Object\AbstractObject; + /** * Class Zend_View_Helper_MonitoringFlags * @@ -64,7 +66,7 @@ class Zend_View_Helper_MonitoringFlags extends Zend_View_Helper_Abstract * @param stdClass $object * @return array */ - public function monitoringFlags(\stdClass $object) + public function monitoringFlags(AbstractObject $object) { $vars = (array)$object; $type = $this->getObjectType($vars); diff --git a/modules/monitoring/application/views/helpers/MonitoringProperties.php b/modules/monitoring/application/views/helpers/MonitoringProperties.php index b7f12ebc7..e25f5fe2b 100644 --- a/modules/monitoring/application/views/helpers/MonitoringProperties.php +++ b/modules/monitoring/application/views/helpers/MonitoringProperties.php @@ -3,6 +3,8 @@ // {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}} +use Icinga\Module\Monitoring\Object\AbstractObject; + /** * Class Zend_View_Helper_MonitoringProperties */ @@ -76,7 +78,7 @@ class Zend_View_Helper_MonitoringProperties extends Zend_View_Helper_Abstract * @param stdClass $object * @return mixed */ - private function getObjectType(stdClass $object) + private function getObjectType(AbstractObject $object) { $keys = array_keys(get_object_vars($object)); $keyParts = explode('_', array_shift($keys), 2); @@ -89,7 +91,7 @@ class Zend_View_Helper_MonitoringProperties extends Zend_View_Helper_Abstract * @param $type * @return object */ - private function dropObjectType(stdClass $object, $type) + private function dropObjectType(AbstractObject $object, $type) { $vars = get_object_vars($object); $out = array(); @@ -248,7 +250,7 @@ class Zend_View_Helper_MonitoringProperties extends Zend_View_Helper_Abstract * @param stdClass $object * @return array */ - public function monitoringProperties(stdClass $object) + public function monitoringProperties(AbstractObject $object) { $type = $this->getObjectType($object); $object = $this->dropObjectType($object, $type); diff --git a/modules/monitoring/application/views/scripts/list/downtimes.phtml b/modules/monitoring/application/views/scripts/list/downtimes.phtml index 3c77fbc04..38d4f9cb2 100644 --- a/modules/monitoring/application/views/scripts/list/downtimes.phtml +++ b/modules/monitoring/application/views/scripts/list/downtimes.phtml @@ -22,7 +22,7 @@ function formatDateString($self,$dateString){
paginationControl( - $downtimes, + $this->downtimes, null, array( 'mixedPagination.phtml', @@ -114,4 +114,4 @@ function formatDateString($self,$dateString){
- \ No newline at end of file + diff --git a/modules/monitoring/application/views/scripts/show/components/command.phtml b/modules/monitoring/application/views/scripts/show/components/command.phtml index fda92c69f..a76fd7f5a 100644 --- a/modules/monitoring/application/views/scripts/show/components/command.phtml +++ b/modules/monitoring/application/views/scripts/show/components/command.phtml @@ -1,7 +1,13 @@ -check_command); - $commandName = array_shift($commandParts); -?> +
+
+ {{CHECK_ICON}} Check Command +
-{{COMMAND_ICON}} Command: -commandArguments($object->check_command); ?> \ No newline at end of file +
+ object->check_command, 2); + array_shift($explodedCommand); + ?> + commandArguments($this->object->check_command); ?> +
+
diff --git a/modules/monitoring/application/views/scripts/show/components/comments.phtml b/modules/monitoring/application/views/scripts/show/components/comments.phtml index b6fd2db88..1ecdf9b46 100644 --- a/modules/monitoring/application/views/scripts/show/components/comments.phtml +++ b/modules/monitoring/application/views/scripts/show/components/comments.phtml @@ -1,18 +1,9 @@ - -comments)): ?> +comments)): ?> comments as $comment) { - if ($this->ticket_pattern) { - $text = preg_replace( - $this->ticket_pattern, - $this->ticket_link, - $this->escape($comment->comment_data) - ); - } else { - $text = $this->escape($comment->comment_data); - } - $list[] = sprintf( +$commets = array(); +foreach ($object->comments as $comment) { + $text = $this->escape($comment->comment_data); + $commets[] = sprintf( '[%s] %s (%s): %s', $this->escape($comment->comment_author), $this->format()->timeSince($comment->comment_timestamp), @@ -21,13 +12,12 @@ foreach ($this->comments as $comment) { ); } ?> -
+
{{COMMENT_ICON}} Comments
-
', $list) ?>
+
', $commets); ?>
- - \ No newline at end of file + diff --git a/modules/monitoring/application/views/scripts/show/components/contacts.phtml b/modules/monitoring/application/views/scripts/show/components/contacts.phtml index 5be7fba98..3256d3ac6 100644 --- a/modules/monitoring/application/views/scripts/show/components/contacts.phtml +++ b/modules/monitoring/application/views/scripts/show/components/contacts.phtml @@ -1,31 +1,51 @@ +contacts)): ?> contacts)) { - $contactList = array(); - foreach ($this->contacts as $contact) { - $contactList[] = 'href( + 'monitoring/show/contact', + array( 'contact_name' => $contact->contact_name - ) - ) . '">' . $contact->contact_alias . ''; - } - - - echo '{{CONTACT_ICON}} Contacts: '; - echo implode(', ', $contactList); - } - - if (!empty($this->contactgroups)) { - $contactGroupList = array(); - foreach ($this->contactgroups as $contactgroup) { - $contactGroupList[] = '' . $contactgroup->contactgroup_alias . ''; - } - echo '{{CONTACTGROUP_ICON}} Contactgroups: '; - echo implode(', ', $contactGroupList); - } + ) + ) + . '">' + . $contact->contact_alias + . ''; +} ?> +
+
+ {{CONTACT_ICON}} Contacts +
+
+ +
+
+ + +contactgroups)): ?> +contactgroups as $contactgroup) { + $contactgroups[] = '' + . $contactgroup->contactgroup_alias + . ''; +} +?> +
+
+ {{CONTACTGROUP_ICON}} Contactgroups +
+
+ +
+
+ diff --git a/modules/monitoring/application/views/scripts/show/components/customvars.phtml b/modules/monitoring/application/views/scripts/show/components/customvars.phtml index 7225953b0..795e0bcf6 100644 --- a/modules/monitoring/application/views/scripts/show/components/customvars.phtml +++ b/modules/monitoring/application/views/scripts/show/components/customvars.phtml @@ -1,4 +1,4 @@ -customvars) && count($this->customvars)) { ?> +customvars) && count($object->customvars)) { ?>
Customvariables @@ -10,7 +10,7 @@ Name Value - customvars as $name => $value) { ?> + customvars as $name => $value) { ?> escape($name) ?> escape($value) ?> diff --git a/modules/monitoring/application/views/scripts/show/components/downtime.phtml b/modules/monitoring/application/views/scripts/show/components/downtime.phtml index 7d9783e56..afeea0349 100644 --- a/modules/monitoring/application/views/scripts/show/components/downtime.phtml +++ b/modules/monitoring/application/views/scripts/show/components/downtime.phtml @@ -29,15 +29,14 @@ ?>
- {{IN_DOWNTIME_ICON}} Downtimes + {{IN_DOWNTIME_ICON}}Downtimes
-
- ', $list); ?> + ', $list); ?>
- \ No newline at end of file + diff --git a/modules/monitoring/application/views/scripts/show/components/flags.phtml b/modules/monitoring/application/views/scripts/show/components/flags.phtml index 28e70909b..2ee03ed95 100644 --- a/modules/monitoring/application/views/scripts/show/components/flags.phtml +++ b/modules/monitoring/application/views/scripts/show/components/flags.phtml @@ -1,16 +1,9 @@ - +
Heading
- if (isset($this->service)) { - $object = $this->service; - } elseif (isset($this->host)) { - $object = $this->host; - } - - $flags = $this->monitoringFlags($object); -?> +
- $value): ?> +monitoringFlags($object) as $name => $value): ?> -
@@ -22,4 +15,6 @@
\ No newline at end of file + +
+
diff --git a/modules/monitoring/application/views/scripts/show/components/hostgroups.phtml b/modules/monitoring/application/views/scripts/show/components/hostgroups.phtml new file mode 100644 index 000000000..d33ccd590 --- /dev/null +++ b/modules/monitoring/application/views/scripts/show/components/hostgroups.phtml @@ -0,0 +1,18 @@ +hostgroups)): ?> +hostgroups as $name => $alias) { + $hostgroups[] = '' + . $alias + . ''; +} +?> +
+
+ {{HOSTGROUP_ICON}} Hostgroups +
+
+ +
+
+ diff --git a/modules/monitoring/application/views/scripts/show/components/perfdata.phtml b/modules/monitoring/application/views/scripts/show/components/perfdata.phtml new file mode 100644 index 000000000..3122253ec --- /dev/null +++ b/modules/monitoring/application/views/scripts/show/components/perfdata.phtml @@ -0,0 +1,10 @@ +object->perfdata): ?> +
+
+ Perfdata +
+
+ perfdata($this->object->perfdata); ?> +
+
+ diff --git a/modules/monitoring/application/views/scripts/show/components/pluginoutput.phtml b/modules/monitoring/application/views/scripts/show/components/pluginoutput.phtml new file mode 100644 index 000000000..98ee0c27f --- /dev/null +++ b/modules/monitoring/application/views/scripts/show/components/pluginoutput.phtml @@ -0,0 +1,9 @@ +
+
+ Plugin Output +
+
+ pluginOutput($this->object->output); ?> + pluginOutput($this->object->long_output); ?> +
+
diff --git a/modules/monitoring/application/views/scripts/show/components/properties.phtml b/modules/monitoring/application/views/scripts/show/components/properties.phtml index 4937596ad..55a10f2ea 100644 --- a/modules/monitoring/application/views/scripts/show/components/properties.phtml +++ b/modules/monitoring/application/views/scripts/show/components/properties.phtml @@ -1,19 +1,15 @@ -service)) { - $object = $this->service; -} elseif (isset($this->host)) { - $object = $this->host; -} - -$properties = $this->monitoringProperties($object); -?> - - $value): ?> - - - - - -
\ No newline at end of file +
+
+ Properties +
+
+ + monitoringProperties($object) as $label => $value): ?> + + + + + +
+
+
diff --git a/modules/monitoring/application/views/scripts/show/components/servicegroups.phtml b/modules/monitoring/application/views/scripts/show/components/servicegroups.phtml index 6e0fb4ab6..d2fdbceaf 100644 --- a/modules/monitoring/application/views/scripts/show/components/servicegroups.phtml +++ b/modules/monitoring/application/views/scripts/show/components/servicegroups.phtml @@ -1,12 +1,18 @@ +servicegroups)): ?> servicegroups)) return; - -$list = array(); +$servicegroups = array(); foreach ($object->servicegroups as $name => $alias) { - $list[] = '' - . $alias - . ''; + $servicegroups[] = '' + . $alias + . ''; } -echo '{{SERVICEGROUP_ICON}} Servicegroups: ' . implode(', ', $list) . "
\n"; - +?> +
+
+ {{SERVICEGROUP_ICON}} Servicegroups +
+
+ +
+
+ diff --git a/modules/monitoring/application/views/scripts/show/header.phtml b/modules/monitoring/application/views/scripts/show/header.phtml index 91141018e..c769fa4ef 100644 --- a/modules/monitoring/application/views/scripts/show/header.phtml +++ b/modules/monitoring/application/views/scripts/show/header.phtml @@ -20,12 +20,7 @@ if (!$this->compact) {
- monitoringCommands( - ($showService === true) ? $this->service : $this->host, - 'small' - ); - ?> +
@@ -33,43 +28,43 @@ if (!$this->compact) { {{HOST_ICON}} - host->host_icon_image): ?> + object->host_icon_image): ?>
- Host image + Host image
- escape($this->host->host_name); ?> - host->host_address && $this->host->host_address !== $this->host->host_name): ?> - (escape($this->host->host_address); ?>) + escape($this->object->host_name); ?> + object->host_address && $this->object->host_address !== $this->object->host_name): ?> + (escape($this->object->host_address); ?>) - host->host_alias) && $this->host->host_alias !== $this->host->host_name): ?> + object->host_alias) && $this->object->host_alias !== $this->object->host_name): ?>
- (host->host_alias; ?>) + (object->host_alias; ?>) - util()->getHostStateName($this->host->host_state); ?> - since timeSince($this->host->host_last_state_change); ?> - host->host_acknowledged === '1'): ?> + util()->getHostStateName($this->object->host_state); ?> + since timeSince($this->object->host_last_state_change); ?> + object->host_acknowledged === '1'): ?> (Has been acknowledged) - host->host_action_url || $this->host->host_notes_url): ?> + object->host_action_url || $this->object->host_notes_url): ?> - host->host_action_url): ?> + object->host_action_url): ?> {{EXTERNAL_LINK_ICON}} - Host actions + Host actions - host->host_notes_url): ?> + object->host_notes_url): ?> {{EXTERNAL_LINK_ICON}} - Host notes + Host notes @@ -116,4 +111,4 @@ if (!$this->compact) {
-
\ No newline at end of file +
diff --git a/modules/monitoring/application/views/scripts/show/host.phtml b/modules/monitoring/application/views/scripts/show/host.phtml index 347d52564..06a02819b 100644 --- a/modules/monitoring/application/views/scripts/show/host.phtml +++ b/modules/monitoring/application/views/scripts/show/host.phtml @@ -1,66 +1,10 @@ -render('show/components/pluginoutput.phtml') ?> -$hostgroupLinkList = array(); -if (!empty($this->hostgroups)) { - foreach ($this->hostgroups as $name => $alias) { - $hostgroupLinkList[] = ''.$alias. ''; - } -} -?> -partial( - 'show/header.phtml', - array( - 'host' => $this->host, - 'service' => $this->service, - 'tabs' => $this->tabs, - 'compact' => $this->compact - ) -); -?> -preview_image ?> -
-
-
- Plugin Output -
-
- pluginOutput($this->host->host_output); ?> - pluginOutput($this->host->host_long_output); ?> -
-
+render('show/components/command.phtml') ?> -
-
- {{CHECK_ICON}} Check Command -
+render('show/components/hostgroups.phtml') ?> -
- host->host_check_command, 2); - array_shift($explodedCommand); - ?> - commandArguments($this->host->host_check_command); ?> -
-
- -
-
- Groups and Contacts -
-
- - {{HOSTGROUP_ICON}} Hostgroups: - - - render('show/components/contacts.phtml') ?> -
-
+render('show/components/contacts.phtml') ?> render('show/components/comments.phtml'); ?> @@ -68,40 +12,6 @@ $this->partial( render('show/components/customvars.phtml'); ?> -host->host_perfdata): ?> -
-
- Perfdata -
-
- perfdata($this->host->host_perfdata); ?> -
-
- +render('show/components/flags.phtml'); ?> -
-
- Flags -
-
- render('show/components/flags.phtml'); ?> -
-
- -
-
- Properties -
-
- render('show/components/properties.phtml'); ?> -
-
- -
-
- {{COMMAND_ICON}} Commands -
-
- monitoringCommands($this->host, 'full'); ?> -
-
\ No newline at end of file +render('show/components/perfdata.phtml'); ?> diff --git a/modules/monitoring/application/views/scripts/show/service.phtml b/modules/monitoring/application/views/scripts/show/service.phtml index f56b0e23d..be1ca49d6 100644 --- a/modules/monitoring/application/views/scripts/show/service.phtml +++ b/modules/monitoring/application/views/scripts/show/service.phtml @@ -1,67 +1,10 @@ -render('show/components/pluginoutput.phtml') ?> -$servicegroupLinkList = array(); -if (!empty($this->servicegroups)) { - foreach ($this->servicegroups as $name => $alias) { - $servicegroupLinkList[] = '' . $alias . ''; - } -} -?> -partial( - 'show/header.phtml', - array( - 'host' => $this->host, - 'service' => $this->service, - 'tabs' => $this->tabs, - 'compact' => $this->compact - ) -); -?> +render('show/components/command.phtml') ?> -preview_image ?> -
-
- Plugin output -
-
- pluginOutput($this->service->service_output); ?> - pluginOutput($this->service->service_long_output); ?> -
-
+render('show/components/contacts.phtml'); ?> -
-
- {{CHECK_ICON}} Check Command -
- -
- service->service_check_command, 2); - echo array_shift($explodedCommand); - ?> - commandArguments($this->service->service_check_command); ?> -
-
- -
-
- {{GROUP_ICON}} Groups and Contacts -
-
- - {{SERVICEGROUP_ICON}} Servicegroups: - - - - render('show/components/contacts.phtml') ?> -
-
+render('show/components/servicegroups.phtml'); ?> render('show/components/comments.phtml'); ?> @@ -69,40 +12,6 @@ $this->partial( render('show/components/customvars.phtml'); ?> -service->service_perfdata): ?> -
-
- Perfdata -
-
- perfdata($this->service->service_perfdata); ?> -
-
- +render('show/components/perfdata.phtml'); ?> -
-
- Flags -
-
- render('show/components/flags.phtml'); ?> -
-
- -
-
- Properties -
-
- render('show/components/properties.phtml'); ?> -
-
- -
-
- {{COMMAND_ICON}} Commands -
-
- monitoringCommands($this->service, 'full'); ?> -
-
\ No newline at end of file +render('show/components/properties.phtml'); ?> diff --git a/modules/monitoring/application/views/scripts/show/services.phtml b/modules/monitoring/application/views/scripts/show/services.phtml deleted file mode 100644 index eb1b5f101..000000000 --- a/modules/monitoring/application/views/scripts/show/services.phtml +++ /dev/null @@ -1,2 +0,0 @@ -render('show/components/header.phtml') ?> - diff --git a/modules/monitoring/library/Monitoring/Backend.php b/modules/monitoring/library/Monitoring/Backend.php index 54579c09d..3f7282d9a 100644 --- a/modules/monitoring/library/Monitoring/Backend.php +++ b/modules/monitoring/library/Monitoring/Backend.php @@ -1,88 +1,121 @@ - * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 - * @author Icinga Development Team - */ // {{{ICINGA_LICENSE_HEADER}}} namespace Icinga\Module\Monitoring; -use \Exception; -use \Icinga\Application\Config as IcingaConfig; -use \Icinga\Authentication\Manager as AuthManager; +use Zend_config; +use Icinga\Application\Config as IcingaConfig; +use Icinga\Exception\ConfigurationError; +use Icinga\Data\DatasourceInterface; +use Icinga\Data\ResourceFactory; +use Icinga\Util\ConfigAwareFactory; -/** - * Container for monitoring backends - */ -class Backend +class Backend implements ConfigAwareFactory, DatasourceInterface { /** - * Array of backends + * Resource config * - * @var array + * @var Zend_config */ - protected static $instances = array(); + private $config; /** - * Array of configuration settings for backends + * The resource the backend utilizes * - * @var array + * @var mixed */ - protected static $backendConfigs; + private $resource; + + private static $backendInstances = array(); + + private static $backendConfigs = array(); /** - * Locked constructor + * Create a new backend from the given resource config + * + * @param Zend_config $config */ - final protected function __construct() + public function __construct(Zend_Config $config) { + $this->config = $config; + $this->resource = ResourceFactory::createResource($config->resource); } /** - * Test if configuration key exist + * Set backend configs * - * @param string $name - * - * @return bool + * @param Zend_Config $backendConfigs */ - public static function exists($name) + public static function setConfig($backendConfigs) { - $configs = self::getBackendConfigs(); - return array_key_exists($name, $configs); + foreach ($backendConfigs as $name => $config) { + self::$backendConfigs[$name] = $config; + } } /** - * Get the first configuration name of all backends + * Backend entry point + * + * return self + */ + public function select() + { + return $this; + } + + /** + * Create query to retrieve columns and rows from the the given table + * + * @param string $table + * @param array $columns + * + * @return Query + */ + public function from($table, array $columns) + { + $queryClass = '\\Icinga\\Module\\Monitoring\\Backend\\' + . ucfirst($this->config->type) + . '\\Query\\' + . ucfirst($table) + . 'Query'; + return new $queryClass($this->resource, $columns); + } + + /** + * Get the resource which was created in the constructor + * + * @return mixed + */ + public function getResource() + { + return $this->resource; + } + + /** + * Get backend configs + * + * @return Zend_Config + */ + public static function getBackendConfigs() + { + if (empty(self::$backendConfigs)) { + self::setConfig(IcingaConfig::module('monitoring', 'backends')); + } + return self::$backendConfigs; + } + + /** + * Retrieve the name of the default backend which is the INI's first entry * * @return string - * - * @throws Exception + * @throws ConfigurationError When no backend has been configured */ - public static function getDefaultName() + public static function getDefaultBackendName() { $configs = self::getBackendConfigs(); if (empty($configs)) { - throw new Exception( + throw new ConfigurationError( 'Cannot get default backend as no backend has been configured' ); } @@ -91,77 +124,32 @@ class Backend } /** - * Getter for backend configuration with lazy initializing + * Create the backend with the given name * - * @return array + * @param $name + * + * @return Backend */ - public static function getBackendConfigs() + public static function createBackend($name) { - if (self::$backendConfigs === null) { - $resources = IcingaConfig::app('resources'); - foreach ($resources as $resource) { - - } - $backends = IcingaConfig::module('monitoring', 'backends'); - foreach ($backends as $name => $config) { - self::$backendConfigs[$name] = $config; - } + if (array_key_exists($name, self::$backendInstances)) { + return self::$backendInstances[$name]; } - return self::$backendConfigs; - } + if ($name === null) { + $name = self::getDefaultBackendName(); + } - /** - * Get a backend by name or a default one - * - * @param string $name - * - * @return AbstractBackend - * - * @throws Exception - */ - public static function getBackend($name = null) - { - if (! array_key_exists($name, self::$instances)) { - if ($name === null) { - $name = self::getDefaultName(); - } else { - if (!self::exists($name)) { - throw new Exception( - sprintf( - 'There is no such backend: "%s"', - $name - ) - ); + $config = self::$backendConfigs[$name]; + self::$backendInstances[$name] = $backend = new self($config); + switch (strtolower($config->type)) { + case 'ido': + if ($backend->getResource()->getDbType() !== 'oracle') { + $backend->getResource()->setTablePrefix('icinga_'); } - } + break; - $config = self::$backendConfigs[$name]; - $type = $config->type; - $type[0] = strtoupper($type[0]); - $class = '\\Icinga\\Module\\Monitoring\\Backend\\' . $type; - self::$instances[$name] = new $class($config); - } - return self::$instances[$name]; - } - - /** - * Get backend by name or by user configuration - * - * @param string $name - * - * @return AbstractBackend - */ - public static function getInstance($name = null) - { - if (array_key_exists($name, self::$instances)) { - return self::$instances[$name]; - } else { - if ($name === null) { - // TODO: Remove this, will be chosen by Environment - $name = AuthManager::getInstance()->getSession()->get('backend'); - } - return self::getBackend($name); } + return $backend; } } diff --git a/modules/monitoring/library/Monitoring/Backend/AbstractBackend.php b/modules/monitoring/library/Monitoring/Backend/AbstractBackend.php index d14d96dc6..b6731285d 100644 --- a/modules/monitoring/library/Monitoring/Backend/AbstractBackend.php +++ b/modules/monitoring/library/Monitoring/Backend/AbstractBackend.php @@ -11,7 +11,7 @@ class AbstractBackend implements DatasourceInterface { protected $config; - public function __construct(Zend_Config $config = null) + public function __construct(Zend_Config $config) { if ($config === null) { // $config = new Zend_Config(array()); ??? @@ -25,7 +25,7 @@ class AbstractBackend implements DatasourceInterface } /** - * Dummy function for fluent code + * Backend entry point * * return self */ diff --git a/modules/monitoring/library/Monitoring/Backend/Ido.php b/modules/monitoring/library/Monitoring/Backend/Ido.php deleted file mode 100644 index 10ede9aca..000000000 --- a/modules/monitoring/library/Monitoring/Backend/Ido.php +++ /dev/null @@ -1,64 +0,0 @@ - - * CREATE INDEX web2_index ON icinga_scheduleddowntime (object_id, is_in_effect); - * CREATE INDEX web2_index ON icinga_comments (object_id); - * CREATE INDEX web2_index ON icinga_objects (object_id, is_active); -- (not sure yet) - * - * - * Other possible (history-related) indexes, still subject to tests: - * CREATE INDEX web2_index ON icinga_statehistory (object_id, state_time DESC); - * CREATE INDEX web2_time ON icinga_statehistory (state_time DESC); - * CREATE INDEX web2_index ON icinga_notifications (object_id, start_time DESC); - * CREATE INDEX web2_start ON icinga_downtimehistory (actual_start_time); - * CREATE INDEX web2_end ON icinga_downtimehistory (actual_end_time); - * CREATE INDEX web2_index ON icinga_commenthistory (object_id, comment_time); - * CREATE INDEX web2_object ON icinga_commenthistory (object_id); - * CREATE INDEX web2_time ON icinga_commenthistory (comment_time DESC); - * - * CREATE INDEX web2_notification_contact ON icinga_contactnotifications (contact_object_id, notification_id); - * - * These should be unique: - * CREATE INDEX web2_index ON icinga_host_contacts (host_id, contact_object_id); - * CREATE INDEX web2_index ON icinga_service_contacts (service_id, contact_object_id); - * - * ...and we should drop a lot's of useless and/or redundant index definitions - */ -class Ido extends AbstractBackend -{ - protected $db; - protected $prefix = 'icinga_'; - - protected function init() - { - $this->db = new Connection($this->config); - if ($this->db->getDbType() === 'oracle') { - $this->prefix = ''; - } - } - - public function getConnection() - { - return $this->db; - } - - /** - * Get our IDO table prefix - * - * return string - */ - public function getPrefix() - { - return $this->prefix; - } -} diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/AbstractQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/AbstractQuery.php index 114b883f0..411b2e539 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/AbstractQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/AbstractQuery.php @@ -34,14 +34,14 @@ abstract class AbstractQuery extends Query { return array_key_exists($column, $this->aggregateColumnIdx); } - + protected function init() { parent::init(); // TODO: $this->applyDbSpecificWorkarounds - $this->prefix = $this->ds->getPrefix(); + $this->prefix = $this->ds->getTablePrefix(); - if ($this->ds->getConnection()->getDbType() === 'oracle') { + if ($this->ds->getDbType() === 'oracle') { $this->object_id = $this->host_id = $this->service_id = $this->hostgroup_id = $this->servicegroup_id = $this->contact_id = $this->contactgroup_id = 'id'; // REALLY? @@ -52,7 +52,7 @@ abstract class AbstractQuery extends Query } } } - if ($this->ds->getConnection()->getDbType() === 'pgsql') { + if ($this->ds->getDbType() === 'pgsql') { foreach ($this->columnMap as $table => & $columns) { foreach ($columns as $key => & $value) { $value = preg_replace('/ COLLATE .+$/', '', $value); @@ -115,7 +115,8 @@ abstract class AbstractQuery extends Query protected function getDefaultColumns() { - $table = array_shift(array_keys($this->columnMap)); + reset($this->columnMap); + $table = key($this->columnMap); return array_keys($this->columnMap[$table]); } diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php index f06405afc..d6f72e952 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationhistoryQuery.php @@ -24,7 +24,7 @@ class NotificationhistoryQuery extends AbstractQuery //"('[' || cndetails.contacts || '] ' || n.output)" // This is one of the db-specific workarounds that could be abstracted // in a better way: - switch ($this->ds->getConnection()->getDbType()) { + switch ($this->ds->getDbType()) { case 'mysql': $concat_contacts = "GROUP_CONCAT(c.alias ORDER BY c.alias SEPARATOR ', ')"; break; @@ -73,7 +73,7 @@ $this->columnMap['history']['output'] = "('[' || $concat_contacts || '] ' || n.o 'cn.contact_object_id = c.contact_object_id', array() )->group('cn.notification_id') - + /*->join( array('cndetails' => $cndetails), 'cndetails.notification_id = n.notification_id', diff --git a/modules/monitoring/library/Monitoring/Backend/Livestatus.php b/modules/monitoring/library/Monitoring/Backend/Livestatus.php deleted file mode 100644 index 46defab3f..000000000 --- a/modules/monitoring/library/Monitoring/Backend/Livestatus.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @author Icinga-Web Team - * @package Icinga\Application - * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License - */ -class Livestatus extends AbstractBackend -{ - protected $connection; - - /** - * Backend initialization starts here - * - * return void - */ - protected function init() - { - $this->connection = new Connection($this->config->socket); - } - - /** - * Get our Livestatus connection - * - * return \Icinga\Protocol\Livestatus\Connection - */ - public function getConnection() - { - return $this->connection; - } -} diff --git a/modules/monitoring/library/Monitoring/Backend/Statusdat.php b/modules/monitoring/library/Monitoring/Backend/Statusdat.php deleted file mode 100755 index 0f674ca5a..000000000 --- a/modules/monitoring/library/Monitoring/Backend/Statusdat.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 - * @author Icinga Development Team - */ -// {{{ICINGA_LICENSE_HEADER}}} - -namespace Icinga\Module\Monitoring\Backend; - -use Icinga\Protocol\Statusdat as StatusdatProtocol; - -/** - * Class Statusdat - * @package Icinga\Backend - */ -class Statusdat extends AbstractBackend -{ - /** - * @var null - */ - private $reader = null; - - /** - * - */ - public function init() - { - $this->reader = new StatusdatProtocol\Reader($this->config); - } - - /** - * @return null - */ - public function getReader() - { - return $this->reader; - } - - /** - * @param array $filter - * @param array $flags - * @return mixed - */ - public function listServices($filter = array(), $flags = array()) - { - $query = $this->select()->from("servicelist"); - return $query->fetchAll(); - } - - /** - * @param $host - * @return MonitoringObjectList|null - */ - public function fetchHost($host, $fetchAll = false) - { - $objs = & $this->reader->getObjects(); - - if (!isset($objs["host"][$host])) { - return null; - } - $result = array($objs["host"][$host]); - return new MonitoringObjectList( - $result, - new StatusdatHostView($this->reader) - ); - } - - /** - * @param $host - * @param $service - * @return MonitoringObjectList|null - */ - public function fetchService($host, $service, $fetchAll = false) - { - $idxName = $host . ";" . $service; - $objs = & $this->reader->getObjects(); - - if (!isset($objs["service"][$idxName])) { - return null; - } - $result = array($objs["service"][$idxName]); - return new MonitoringObjectList( - $result, - new StatusdatServiceView($this->reader) - ); - - } -} diff --git a/modules/monitoring/library/Monitoring/DataView/DataView.php b/modules/monitoring/library/Monitoring/DataView/DataView.php new file mode 100644 index 000000000..bf3686754 --- /dev/null +++ b/modules/monitoring/library/Monitoring/DataView/DataView.php @@ -0,0 +1,176 @@ +query = $ds->select()->from(static::getTableName(), $columns === null ? $this->getColumns() : $columns); + } + + /** + * Get the queried table name + * + * @return string + */ + public static function getTableName() + { + $tableName = explode('\\', get_called_class()); + $tableName = strtolower(end($tableName)); + return $tableName; + } + + /** + * Retrieve columns provided by this view + * + * @return array + */ + abstract public function getColumns(); + + /** + * Retrieve default sorting rules for particular columns. These involve sort order and potential additional to sort + * + * @return array + */ + abstract public function getSortRules(); + + public function getFilterColumns() + { + return array(); + } + + /** + * Create view from request + * + * @param Request $request + * @param array $columns + * + * @return static + */ + public static function fromRequest(Request $request, array $columns = null) + { + $view = new static(Backend::createBackend($request->getParam('backend')), $columns); + $view->filter($request->getParams()); + $order = $request->getParam('dir'); + if ($order !== null) { + if (strtolower($order) === 'desc') { + $order = self::SORT_DESC; + } else { + $order = self::SORT_ASC; + } + } + $view->sort( + $request->getParam('sort'), + $order + ); + return $view; + } + + /** + * Filter rows that match all of the given filters. If a filter is not valid, it's silently ignored + * + * @param array $filters + * + * @see isValidFilterColumn() + */ + public function filter(array $filters) + { + foreach ($filters as $column => $filter) { + if ($this->isValidFilterColumn($column)) { + $this->query->where($column, $filter); + } + } + } + + /** + * Check whether the given column is a valid filter column, i.e. the view actually provides the column or it's + * a non-queryable filter column + * + * @param string $column + * + * @return bool + */ + protected function isValidFilterColumn($column) + { + return in_array($column, $this->getColumns()) || in_array($column, $this->getFilterColumns()); + } + + /** + * Sort the rows, according to the specified sort column and order + * + * @param string $column Sort column + * @param int $order Sort order, one of the SORT_ constants + * + * @see DataView::SORT_ASC + * @see DataView::SORT_DESC + */ + public function sort($column = null, $order = null) + { + $sortRules = $this->getSortRules(); + if ($column === null) { + $sortColumns = reset($sortRules); + if (!isset($sortColumns['columns'])) { + $sortColumns['columns'] = array(key($sortRules)); + } + } else { + if (isset($sortRules[$column])) { + $sortColumns = $sortRules[$column]; + if (!isset($sortColumns['columns'])) { + $sortColumns['columns'] = array($column); + } + } else { + $sortColumns = array( + 'columns' => array($column), + 'order' => $order + ); + }; + } + $order = $order === null ? (isset($sortColumns['order']) ? $sortColumns['order'] : self::SORT_ASC) : $order; + foreach ($sortColumns['columns'] as $column) { + $this->query->order($column, $order); + } + } + + /** + * Return the query which was created in the constructor + * + * @return mixed + */ + public function getQuery() + { + return $this->query; + } +} diff --git a/modules/monitoring/library/Monitoring/DataView/Downtime.php b/modules/monitoring/library/Monitoring/DataView/Downtime.php new file mode 100644 index 000000000..05a367b7e --- /dev/null +++ b/modules/monitoring/library/Monitoring/DataView/Downtime.php @@ -0,0 +1,50 @@ + array( + 'order' => self::SORT_DESC + ), + 'downtime_actual_start_time' => array( + 'order' => self::SORT_DESC + ) + ); + } +} diff --git a/modules/monitoring/library/Monitoring/DataView/HostAndServiceStatus.php b/modules/monitoring/library/Monitoring/DataView/HostAndServiceStatus.php new file mode 100644 index 000000000..bd3771459 --- /dev/null +++ b/modules/monitoring/library/Monitoring/DataView/HostAndServiceStatus.php @@ -0,0 +1,131 @@ + array( + 'order' => self::SORT_ASC + ), + 'host_address' => array( + 'columns' => array( + 'host_ipv4', + 'service_description' + ), + 'order' => self::SORT_ASC + ), + 'host_last_state_change' => array( + 'order' => self::SORT_ASC + ), + 'host_severity' => array( + 'columns' => array( + 'host_severity', + 'host_last_state_change', + ), + 'order' => self::SORT_ASC + ) + ); + } + + public function getFilterColumns() + { + return array('hostgroups', 'servicegroups'); + } + + protected function isValidFilterColumn($column) + { + if ($column[0] === '_' + && preg_match('/^_(?:host|service)_/', $column) + ) { + return true; + } + return parent::isValidFilterColumn($column); + } +} diff --git a/modules/monitoring/library/Monitoring/DataView/Notification.php b/modules/monitoring/library/Monitoring/DataView/Notification.php new file mode 100644 index 000000000..ac9a6da84 --- /dev/null +++ b/modules/monitoring/library/Monitoring/DataView/Notification.php @@ -0,0 +1,41 @@ + array( + 'order' => self::SORT_DESC + ) + ); + } + + public function getTableName() + { + + } +} diff --git a/modules/monitoring/library/Monitoring/Object/AbstractObject.php b/modules/monitoring/library/Monitoring/Object/AbstractObject.php index 234fc3504..666572938 100644 --- a/modules/monitoring/library/Monitoring/Object/AbstractObject.php +++ b/modules/monitoring/library/Monitoring/Object/AbstractObject.php @@ -3,7 +3,7 @@ namespace Icinga\Module\Monitoring\Object; use Icinga\Data\AbstractQuery as Query; -use \Icinga\Module\Monitoring\Backend\AbstractBackend; +use \Icinga\Module\Monitoring\Backend; abstract class AbstractObject { @@ -26,7 +26,7 @@ abstract class AbstractObject // 'comments' => null, ); - public function __construct(AbstractBackend $backend, $name1, $name2 = null) + public function __construct(Backend $backend, $name1, $name2 = null) { $this->backend = $backend; $this->name1 = $name1; @@ -34,7 +34,7 @@ abstract class AbstractObject $this->properties = (array) $this->fetchObject(); } - public static function fetch(AbstractBackend $backend, $name1, $name2 = null) + public static function fetch(Backend $backend, $name1, $name2 = null) { return new static($backend, $name1, $name2); } diff --git a/modules/monitoring/library/Monitoring/Object/Service.php b/modules/monitoring/library/Monitoring/Object/Service.php index b79894e86..ba9d0ea11 100644 --- a/modules/monitoring/library/Monitoring/Object/Service.php +++ b/modules/monitoring/library/Monitoring/Object/Service.php @@ -31,8 +31,7 @@ class Service extends AbstractObject ->fetchContacts() ->fetchContactgroups() ->fetchCustomvars() - ->fetchComments() - ; + ->fetchComments(); } protected function fetchObject()