diff --git a/modules/monitoring/library/Monitoring/Object/MonitoredObject.php b/modules/monitoring/library/Monitoring/Object/MonitoredObject.php index 8ff79f7b8..cb95c2e41 100644 --- a/modules/monitoring/library/Monitoring/Object/MonitoredObject.php +++ b/modules/monitoring/library/Monitoring/Object/MonitoredObject.php @@ -2,127 +2,249 @@ // {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}} -/* -CREATE INDEX tgelf_comments ON icinga_comments (object_id, comment_type, comment_time); - -CREATE INDEX tgelf_scheduleddowntime ON icinga_scheduleddowntime (object_id, is_in_effect, scheduled_start_time); - -*/ - namespace Icinga\Module\Monitoring\Object; -use Icinga\Module\Monitoring\DataView\Contact; -use Icinga\Module\Monitoring\DataView\Contactgroup; -use Icinga\Module\Monitoring\DataView\Downtime; -use Icinga\Module\Monitoring\DataView\EventHistory; -use Icinga\Module\Monitoring\DataView\Hostgroup; -use Icinga\Module\Monitoring\DataView\Comment; -use Icinga\Module\Monitoring\DataView\Servicegroup; -use Icinga\Module\Monitoring\DataView\Customvar; -use Icinga\Web\UrlParams; +use InvalidArgumentException; use Icinga\Application\Config; +use Icinga\Exception\InvalidPropertyException; +use Icinga\Module\Monitoring\Backend; - +/** + * A monitored Icinga object, i.e. host or service + */ abstract class MonitoredObject { - public $type; - public $prefix; + /** + * Type host + */ + const TYPE_HOST = 'host'; - public $comments = array(); - public $downtimes = array(); - public $hostgroups = array(); - public $servicegroups = array(); - public $contacts = array(); - public $contactgroups = array(); - public $customvars = array(); - public $events = array(); + /** + * Type service + */ + const TYPE_SERVICE = 'service'; - protected $view; - private $properties = array(); - protected $params; + /** + * Backend to fetch object information from + * + * @var Backend + */ + protected $backend; - // TODO: Fetching parent states if any would be nice - // Same goes for host/service dependencies + /** + * Type of the Icinga object, i.e. 'host' or 'service' + * + * @var string + */ + protected $type; - public function __construct(UrlParams $params) + /** + * Prefix of the Icinga object, i.e. 'host_' or 'service_' + * + * @var string + */ + protected $prefix; + + /** + * Properties + * + * @var object + */ + protected $properties; + + /** + * Comments + * + * @var array + */ + protected $comments; + + /** + * Downtimes + * + * @var array + */ + protected $downtimes; + + /** + * Host groups + * + * @var array + */ + protected $hostgroups; + + /** + * Service groups + * + * @var array + */ + protected $servicegroups; + + /** + * Contacts + * + * @var array + */ + protected $contacts; + + /** + * Contact groups + * + * @var array + */ + protected $contactgroups; + + /** + * Custom variables + * + * @var array + */ + protected $customvars; + + /** + * Event history + * + * @var \Icinga\Module\Monitoring\DataView\EventHistory + */ + protected $eventhistory; + + /** + * Create a monitored object, i.e. host or service + * + * @param Backend $backend Backend to fetch object information from + */ + public function __construct(Backend $backend) { - $this->params = $params; - $this->properties = $this->getProperties(); + $this->backend = $backend; } - abstract protected function getProperties(); + /** + * Get the object's data view + * + * @return \Icinga\Module\Monitoring\DataView\DataView + */ + abstract protected function getDataView(); + /** + * Fetch the object's properties + * + * @return bool + */ + public function fetch() + { + $this->properties = $this->getDataView()->getQuery()->fetchRow(); + return $this->properties !== false; + } + + /** + * Get the type of the object + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Require the object's type to be one of the given types + * + * @param array $oneOf + * + * @return bool + * @throws InvalidArgumentException If the object's type is not one of the given types. + */ + public function assertOneOf(array $oneOf) + { + if (! in_array($this->type, $oneOf)) { + throw new InvalidArgumentException; + } + return true; + } + + /** + * Fetch the object's comments + * + * @return $this + */ public function fetchComments() { - // WTF??? - $query = Comment::fromParams(array('backend' => null), array( + $comments = $this->backend->select()->from('comment', array( 'id' => 'comment_internal_id', 'timestamp' => 'comment_timestamp', 'author' => 'comment_author', 'comment' => 'comment_data', 'type' => 'comment_type', - )); - $query->where('comment_type', array('comment', 'ack')); - $query->where('comment_objecttype', $this->type); - $query->where('comment_host', $this->host_name); - if ($this->type === 'service') { - $query->where('comment_service', $this->service_description); + )) + ->where('comment_type', array('comment', 'ack')) + ->where('comment_objecttype', $this->type) + ->where('comment_host', $this->host); + if ($this->type === self::TYPE_SERVICE) { + $comments->where('comment_service', $this->service); } - $this->comments = $query->getQuery()->fetchAll(); + $this->comments = $comments->getQuery()->fetchAll(); return $this; } + /** + * Fetch the object's downtimes + * + * @return $this + */ public function fetchDowntimes() { - // TODO: We want to check for objecttype = 'host', not type_id = 1 - - // WTF??? - $query = Downtime::fromParams(array('backend' => null), array( - 'id' => 'downtime_internal_id', - 'objecttype' => 'downtime_objecttype', - 'comment' => 'downtime_comment', - 'author' => 'downtime_author', - 'start' => 'downtime_start', - 'scheduled_start' => 'downtime_scheduled_start', - 'end' => 'downtime_end', - 'duration' => 'downtime_duration', - 'is_flexible' => 'downtime_is_flexible', - 'is_fixed' => 'downtime_is_fixed', - 'is_in_effect' => 'downtime_is_in_effect', - 'entry_time' => 'downtime_entry_time', - 'host' => 'downtime_host', - 'service' => 'downtime_service' - )); - - $query->where('downtime_objecttype', $this->type); - $query->where('downtime_host', $this->host_name); - if ($this->type === 'service') { - $query->where('downtime_service', $this->service_description); + $downtimes = $this->backend->select()->from('downtime', array( + 'id' => 'downtime_internal_id', + 'objecttype' => 'downtime_objecttype', + 'comment' => 'downtime_comment', + 'author' => 'downtime_author', + 'start' => 'downtime_start', + 'scheduled_start' => 'downtime_scheduled_start', + 'end' => 'downtime_end', + 'duration' => 'downtime_duration', + 'is_flexible' => 'downtime_is_flexible', + 'is_fixed' => 'downtime_is_fixed', + 'is_in_effect' => 'downtime_is_in_effect', + 'entry_time' => 'downtime_entry_time', + 'host' => 'downtime_host', + 'service' => 'downtime_service' + )) + ->where('downtime_objecttype', $this->type) + ->where('downtime_host', $this->host) + ->order('downtime_is_in_effect', 'DESC') + ->order('downtime_scheduled_start', 'ASC'); + if ($this->type === self::TYPE_SERVICE) { + $downtimes->where('downtime_service', $this->service); } - $query->order('downtime_is_in_effect', 'DESC')->order('downtime_scheduled_start', 'ASC'); - - $this->downtimes = $query->getQuery()->fetchAll(); - return $this; - - $this->downtimes = Downtime::fromRequest($this->request)->getQuery()->fetchAll(); + $this->downtimes = $downtimes->getQuery()->fetchAll(); return $this; } + /** + * Fetch the object's host groups + * + * @return $this + */ public function fetchHostgroups() { - $query = HostGroup::fromParams(array('backend' => null), array( + $hostGroups = $this->backend->select()->from('hostGroup', array( 'hostgroup_name', 'hostgroup_alias' - ))->where('host_name', $this->host_name); - - $this->hostgroups = $query->getQuery()->fetchPairs(); + )) + ->where('host_name', $this->host); + $this->hostgroups = $hostGroups->getQuery()->fetchPairs(); return $this; } + /** + * Fetch the object's custom variables + * + * @return $this + */ public function fetchCustomvars() { $blacklist = array(); - $blacklistPattern = '/^(.*pw.*|.*pass.*|community)$/'; + $blacklistPattern = '/^(.*pw.*|.*pass.*|community)$/i'; if ($security = Config::module('monitoring')->get('security')) { @@ -138,23 +260,20 @@ abstract class MonitoredObject $blacklistPattern = '/^(' . implode('|', $blacklist) . ')$/i'; } - $query = Customvar::fromParams(array('backend' => null), array( - 'varname', - 'varvalue' - ) - ); - - if ($this->type === 'host') { - $query->where('host_name', $this->host_name) - ->where('object_type', 'host'); - } else { - $query->where('host_name', $this->host_name) - ->where('object_type', 'service') - ->where('service_description', $this->service_description); + $query = $this->backend->select()->from('customvar', array( + 'varname', + 'varvalue' + )) + ->where('object_type', $this->type) + ->where('host_name', $this->host); + if ($this->type === self::TYPE_SERVICE) { + $query->where('service_description', $this->service); } + $this->customvars = array(); + $customvars = $query->getQuery()->fetchPairs(); - foreach ($customvars as $name => &$value) { + foreach ($customvars as $name => $value) { $name = ucwords(str_replace('_', ' ', strtolower($name))); if ($blacklistPattern && preg_match($blacklistPattern, $name)) { $value = '***'; @@ -165,83 +284,71 @@ abstract class MonitoredObject return $this; } + /** + * Fetch the object's contacts + * + * @return $this + */ public function fetchContacts() { -/* - $query = Contact::fromRequest( - $this->request, - array( + $contacts = $this->backend->select()->from('contact', array( 'contact_name', 'contact_alias', 'contact_email', 'contact_pager', - ) - )->getQuery() + )) ->where('host_name', $this->host_name); -*/ - - $query = Contact::fromParams(array('backend' => null), array( - 'contact_name', - 'contact_alias', - 'contact_email', - 'contact_pager', - )); - - if ($this->type === 'service') { - $query->where('service_host_name', $this->host_name); - $query->where('service_description', $this->service_description); - } else { - $query->where('host_name', $this->host_name); + if ($this->type === self::TYPE_SERVICE) { + $contacts->where('service_description', $this->service); } - - $this->contacts = $query->getQuery()->fetchAll(); + $this->contacts = $contacts->getQuery()->fetchAll(); return $this; } + /** + * Fetch the object's service groups + * + * @return $this + */ public function fetchServicegroups() { - $query = Servicegroup::fromParams(array('backend' => null), array( + $serviceGroups = $this->backend->select()->from('serviceGroup', array( 'servicegroup_name', - 'servicegroup_alias', - ) - ); - $query->where('service_host_name', $this->host_name); - $query->where('service_description', $this->service_description); - $this->servicegroups = $query->getQuery()->fetchPairs(); + 'servicegroup_alias' + )) + ->where('service_host_name', $this->host) + ->where('service_description', $this->service); + $this->servicegroups = $serviceGroups->getQuery()->fetchPairs(); return $this; } + /** + * Fetch the object's contact groups + * + * @return $this + */ public function fetchContactgroups() { - - $query = Contactgroup::fromParams(array('backend' => null), array( + $contactsGroups = $this->backend->select()->from('contactGroup', array( 'contactgroup_name', 'contactgroup_alias' - )); - - if ($this->type === 'service') { - $query->where('service_host_name', $this->host_name); - $query->where('service_description', $this->service_description); - } else { - $query->where('host_name', $this->host_name); + )) + ->where('host_name', $this->host); + if ($this->type === self::TYPE_SERVICE) { + $contactsGroups->where('service_description', $this->service); } -/* - $query = Contactgroup::fromRequest( - $this->request, - array( - 'contactgroup_name', - 'contactgroup_alias' - ) - )->getQuery(); -*/ - $this->contactgroups = $query->getQuery()->fetchAll(); - + $this->contactgroups = $contactsGroups->getQuery()->fetchAll(); return $this; } - public function fetchEventHistory() + /** + * Fetch the object's event history + * + * @return $this + */ + public function fetchEventhistory() { - $query = EventHistory::fromParams(array('backend' => null), array( + $eventHistory = $this->backend->select()->from('eventHistory', array( 'object_type', 'host_name', 'service_description', @@ -251,42 +358,50 @@ abstract class MonitoredObject 'max_attempts', 'output', 'type' - ) - )->sort('timestamp', 'DESC'); - if ($this->type === 'service') { - $query->where('service_host_name', $this->host_name); - $query->where('service_description', $this->service_description); - } else { - $query->where('host_name', $this->host_name); + )) + ->order('timestamp', 'DESC') + ->where('host_name', $this->host); + if ($this->type === self::TYPE_SERVICE) { + $eventHistory->where('service_description', $this->service); } - - $this->eventhistory = $query->getQuery(); + $this->eventhistory = $eventHistory->getQuery(); return $this; } - public function __get($param) + /** + * Fetch all available data of the object + * + * @return $this + */ + public function populate() { - - if (isset($this->properties->$param)) { - return $this->properties->$param; - } elseif (isset($this->$param)) { - return $this->$param; - } - if (substr($param, 0, strlen($this->prefix)) === $this->prefix) { - return false; - } - $expandedName = $this->prefix . strtolower($param); - return $this->$expandedName; + $this + ->fetchComments() + ->fetchContacts() + ->fetchContactgroups() + ->fetchCustomvars() + ->fetchDowntimes(); + // Call fetchHostgroups or fetchServicegroups depending on the object's type + $fetchGroups = 'fetch' . ucfirst($this->type) . 'groups'; + $this->$fetchGroups(); + return $this; } - public static function fromParams(UrlParams $params) + public function __get($name) { - if ($params->has('service') && $params->has('host')) { - return new Service($params); - } elseif ($params->has('host')) { - return new Host($params); + if (property_exists($this->properties, $name)) { + return $this->properties->$name; + } elseif (isset($this->$name)) { + return $this->$name; + } elseif (property_exists($this, $name)) { + $fetchMethod = 'fetch' . ucfirst($name); + $this->$fetchMethod(); + return $this->$name; } + if (substr($name, 0, strlen($this->prefix)) === $this->prefix) { + throw new InvalidPropertyException('Can\'t access property \'%s\'. Property does not exist.', $name); + } + $prefixedName = $this->prefix . strtolower($name); + return $this->$prefixedName; } - - abstract public function populate(); }