diff options
Diffstat (limited to 'application/controllers/DataController.php')
-rw-r--r-- | application/controllers/DataController.php | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/application/controllers/DataController.php b/application/controllers/DataController.php new file mode 100644 index 0000000..c6051eb --- /dev/null +++ b/application/controllers/DataController.php @@ -0,0 +1,213 @@ +<?php + +namespace Icinga\Module\Map\Controllers; + +use Icinga\Data\Filter\Filter; +use Icinga\Module\Monitoring\Controller; +use Icinga\Module\Monitoring\DataView\DataView; + +class DataController extends Controller +{ + /** + * Apply filters on a DataView + * + * @param DataView $dataView The DataView to apply filters on + * + * @return DataView $dataView + */ + protected function filterQuery(DataView $dataView) + { + $this->setupFilterControl($dataView, null, null, ['stateType', 'objectType', 'problems']); + return $dataView; + } + + private $stateColumn; + private $stateChangeColumn; + + /** + * Get JSON state objects + */ + public function pointsAction() + { + $points = array(); + + try { + // Borrowed from monitoring module + // Handle soft and hard states + $config = $this->config(); + $stateType = strtolower($this->params->shift('stateType', + $config->get('map', 'stateType', 'soft') + )); + + $userPreferences = $this->Auth()->getUser()->getPreferences(); + if ($userPreferences->has("map")) { + $stateType = $userPreferences->getValue("map", "stateType", $stateType); + } + + $filter = (bool)$this->params->shift('problems', false) ? Filter::where('service_problem', 1) : null; + + $objectType = strtolower($this->params->shift('objectType', 'all')); + + if ($stateType === 'hard') { + $this->stateColumn = 'hard_state'; + $this->stateChangeColumn = 'last_hard_state_change'; + } else { + $this->stateColumn = 'state'; + $this->stateChangeColumn = 'last_state_change'; + } + + if (in_array($objectType, ['all', 'host'])) { + // get host data + $hostQuery = $this->backend + ->select() + ->from('hoststatus', array( + 'host_display_name', + 'host_name', + 'host_acknowledged', + 'host_state' => 'host_' . $this->stateColumn, + 'host_last_state_change' => 'host_' . $this->stateChangeColumn, + 'host_in_downtime', + 'host_problem', + 'coordinates' => '_host_geolocation', + 'icon' => '_host_map_icon', + )) + ->applyFilter(Filter::fromQueryString('_host_geolocation >')); + + $this->applyRestriction('monitoring/filter/objects', $hostQuery); + $this->filterQuery($hostQuery); + + // get service data + $serviceQuery = $this->backend + ->select() + ->from('servicestatus', array( + 'host_name', + 'service_display_name', + 'service_name' => 'service', + 'service_acknowledged', + 'service_state' => 'service_' . $this->stateColumn, + 'service_last_state_change' => 'service_' . $this->stateChangeColumn, + 'service_in_downtime' + )) + ->applyFilter(Filter::fromQueryString('_host_geolocation >')); + + if ($filter) { + $serviceQuery->applyFilter($filter); + } + + $this->applyRestriction('monitoring/filter/objects', $serviceQuery); + $this->filterQuery($serviceQuery); + + if ($hostQuery->count() > 0) { + foreach ($hostQuery as $row) { + $hostname = $row->host_name; + + $host = (array)$row; + $host['services'] = array(); + + // check for broken coordinates + $coordinate_pattern = '/^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/'; + + if (!preg_match($coordinate_pattern, $host['coordinates'])) { + continue; + } + + $host['coordinates'] = explode(",", $host['coordinates']); + + $points['hosts'][$hostname] = $host; + } + } + + // add services to host + if ($serviceQuery->count() > 0) { + foreach ($serviceQuery as $row) { + $hostname = $row->host_name; + + $service = (array)$row; + unset($service['host_name']); + + if (isset($points['hosts'][$hostname])) { + $points['hosts'][$hostname]['services'][$service['service_display_name']] = $service; + } + } + } + + // remove hosts without problems and services + if ($filter) { + foreach ($points['hosts'] as $name => $host) { + if (empty($host['services']) && $host['host_problem'] != '1') { + unset($points['hosts'][$name]); + } + } + } + } + + if (in_array($objectType, ['all', 'service'])) { + + // get services with geolocation + $geoServiceQuery = $this->backend + ->select() + ->from('servicestatus', array( + 'host_display_name', + 'host_name', + 'host_acknowledged', + 'host_state' => 'host_' . $this->stateColumn, + 'host_last_state_change' => 'host_' . $this->stateChangeColumn, + 'host_in_downtime', + 'service_display_name', + 'service_name' => 'service', + 'service_acknowledged', + 'service_state' => 'service_' . $this->stateColumn, + 'service_last_state_change' => 'service_' . $this->stateChangeColumn, + 'service_in_downtime', + 'coordinates' => '_service_geolocation', + 'icon' => '_service_map_icon', + + ))->applyFilter(Filter::fromQueryString('_service_geolocation >')); + + if ($filter) { + $geoServiceQuery->applyFilter($filter); + } + + + $this->applyRestriction('monitoring/filter/objects', $geoServiceQuery); + $this->filterQuery($geoServiceQuery); + // --- + + if ($geoServiceQuery->count() > 0) { + foreach ($geoServiceQuery as $row) { + $identifier = $row->host_name . "!" . $row->service_name; + + $ar = (array)$row; + + $host = array_filter($ar, function ($k) { + return (preg_match("/^host_|^coordinates/", $k)); + }, ARRAY_FILTER_USE_KEY); + + $service = array_filter($ar, function ($k) { + return (preg_match("/^service_/", $k)); + }, ARRAY_FILTER_USE_KEY); + + $host['services'][$service['service_display_name']] = $service; + + // check for broken coordinates + $coordinate_pattern = '/^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/'; + + if (!preg_match($coordinate_pattern, $host['coordinates'])) { + continue; + } + + $host['coordinates'] = explode(",", $host['coordinates']); + $host['icon'] = $ar['icon']; + $points['services'][$identifier] = $host; + } + } + } + } catch (\Exception $e) { + $points['message'] = $e->getMessage(); + $points['trace'] = $e->getTraceAsString(); + } + + echo json_encode($points); + exit(); + } +} |