1<?php 2// Icinga Web 2 Cube Module | (c) 2016 Icinga GmbH | GPLv2 3 4namespace Icinga\Module\Cube\Ido; 5 6use Icinga\Application\Config; 7use Icinga\Authentication\Auth; 8use Icinga\Data\Filter\Filter; 9use Icinga\Exception\ConfigurationError; 10use Icinga\Exception\QueryException; 11use Icinga\Module\Cube\DbCube; 12use Icinga\Module\Monitoring\Backend\MonitoringBackend; 13use Icinga\Util\GlobFilter; 14 15/** 16 * IdoCube 17 * 18 * Base class for IDO-related cubes 19 * 20 * @package Icinga\Module\Cube\Ido 21 */ 22abstract class IdoCube extends DbCube 23{ 24 /** @var array */ 25 protected $availableFacts = array(); 26 27 /** @var string We ask for the IDO version for compatibility reasons */ 28 protected $idoVersion; 29 30 /** @var MonitoringBackend */ 31 protected $backend; 32 33 /** 34 * Cache for {@link filterProtectedCustomvars()} 35 * 36 * @var string|null 37 */ 38 protected $protectedCustomvars; 39 40 /** @var GlobFilter The properties to hide from the user */ 41 protected $blacklistedProperties; 42 43 /** 44 * We can steal the DB connection directly from a Monitoring backend 45 * 46 * @param MonitoringBackend $backend 47 * @return $this 48 */ 49 public function setBackend(MonitoringBackend $backend) 50 { 51 $this->backend = $backend; 52 53 $this->setConnection($backend->getResource()); 54 55 return $this; 56 } 57 58 /** 59 * Provice access to our DB resource 60 * 61 * This lazy-loads the default monitoring backend in case no DB has been 62 * given 63 * 64 * @return \Zend_Db_Adapter_Abstract 65 */ 66 public function db() 67 { 68 $this->requireBackend(); 69 return parent::db(); 70 } 71 72 /** 73 * Returns the Icinga IDO version 74 * 75 * @return string 76 */ 77 protected function getIdoVersion() 78 { 79 if ($this->idoVersion === null) { 80 $db = $this->db(); 81 $this->idoVersion = $db->fetchOne( 82 $db->select()->from('icinga_dbversion', 'version') 83 ); 84 } 85 86 return $this->idoVersion; 87 } 88 89 /** 90 * Steal the default monitoring DB resource... 91 * 92 * ...in case none has been defined otherwise 93 * 94 * @return void 95 */ 96 protected function requireBackend() 97 { 98 if ($this->db === null) { 99 $this->setBackend(MonitoringBackend::instance()); 100 } 101 } 102 103 protected function getMonitoringRestriction() 104 { 105 $restriction = Filter::matchAny(); 106 $restriction->setAllowedFilterColumns(array( 107 'host_name', 108 'hostgroup_name', 109 'instance_name', 110 'service_description', 111 'servicegroup_name', 112 function ($c) { 113 return preg_match('/^_(?:host|service)_/i', $c); 114 } 115 )); 116 117 $filters = Auth::getInstance()->getUser()->getRestrictions('monitoring/filter/objects'); 118 119 foreach ($filters as $filter) { 120 if ($filter === '*') { 121 return Filter::matchAny(); 122 } 123 try { 124 $restriction->addFilter(Filter::fromQueryString($filter)); 125 } catch (QueryException $e) { 126 throw new ConfigurationError( 127 'Cannot apply restriction %s using the filter %s. You can only use the following columns: %s', 128 'monitoring/filter/objects', 129 $filter, 130 implode(', ', array( 131 'instance_name', 132 'host_name', 133 'hostgroup_name', 134 'service_description', 135 'servicegroup_name', 136 '_(host|service)_<customvar-name>' 137 )), 138 $e 139 ); 140 } 141 } 142 143 return $restriction; 144 } 145 146 /** 147 * Return the given array without values matching the custom variables protected by the monitoring module 148 * 149 * @param string[] $customvars 150 * 151 * @return string[] 152 */ 153 protected function filterProtectedCustomvars(array $customvars) 154 { 155 if ($this->blacklistedProperties === null) { 156 $this->blacklistedProperties = new GlobFilter( 157 Auth::getInstance()->getRestrictions('monitoring/blacklist/properties') 158 ); 159 } 160 161 if ($this instanceof IdoServiceStatusCube) { 162 $type = 'service'; 163 } else { 164 $type = 'host'; 165 } 166 167 $customvars = $this->blacklistedProperties->removeMatching( 168 [$type => ['vars' => array_flip($customvars)]] 169 ); 170 171 $customvars = isset($customvars[$type]['vars']) ? array_flip($customvars[$type]['vars']) : []; 172 173 if ($this->protectedCustomvars === null) { 174 $config = Config::module('monitoring')->get('security', 'protected_customvars'); 175 $protectedCustomvars = array(); 176 177 foreach (preg_split('~,~', $config, -1, PREG_SPLIT_NO_EMPTY) as $pattern) { 178 $regex = array(); 179 foreach (explode('*', $pattern) as $literal) { 180 $regex[] = preg_quote($literal, '/'); 181 } 182 183 $protectedCustomvars[] = implode('.*', $regex); 184 } 185 186 $this->protectedCustomvars = empty($protectedCustomvars) 187 ? '/^$/' 188 : '/^(?:' . implode('|', $protectedCustomvars) . ')$/'; 189 } 190 191 return preg_grep($this->protectedCustomvars, $customvars, PREG_GREP_INVERT); 192 } 193} 194