summaryrefslogtreecommitdiffstats
path: root/library/Icingadb/Compat/CompatObject.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Icingadb/Compat/CompatObject.php')
-rw-r--r--library/Icingadb/Compat/CompatObject.php373
1 files changed, 373 insertions, 0 deletions
diff --git a/library/Icingadb/Compat/CompatObject.php b/library/Icingadb/Compat/CompatObject.php
new file mode 100644
index 0000000..d9d72a3
--- /dev/null
+++ b/library/Icingadb/Compat/CompatObject.php
@@ -0,0 +1,373 @@
+<?php
+
+/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
+
+namespace Icinga\Module\Icingadb\Compat;
+
+use Icinga\Exception\NotImplementedError;
+use Icinga\Module\Icingadb\Common\Auth;
+use Icinga\Module\Icingadb\Common\Database;
+use Icinga\Module\Icingadb\Model\CustomvarFlat;
+use Icinga\Module\Icingadb\Model\Host;
+use Icinga\Module\Icingadb\Model\Service;
+use Icinga\Module\Icingadb\Model\Servicegroup;
+use Icinga\Module\Icingadb\Model\ServicestateSummary;
+use InvalidArgumentException;
+use ipl\Orm\Model;
+use ipl\Orm\Query;
+use ipl\Stdlib\Filter;
+use LogicException;
+
+use function ipl\Stdlib\get_php_type;
+
+trait CompatObject
+{
+ use Auth;
+ use Database;
+
+ /** @var array Non-obscured custom variables */
+ protected $rawCustomvars;
+
+ /** @var array Non-obscured host custom variables */
+ protected $rawHostCustomvars;
+
+ /** @var Model $object */
+ private $object;
+
+ public function __construct(Model $object)
+ {
+ $this->object = $object;
+ }
+
+ public static function fromModel(Model $object)
+ {
+ switch (true) {
+ case $object instanceof Host:
+ return new CompatHost($object);
+ case $object instanceof Service:
+ return new CompatService($object);
+ default:
+ throw new InvalidArgumentException(sprintf(
+ 'Host or Service Model instance expected, got "%s" instead.',
+ get_php_type($object)
+ ));
+ }
+ }
+
+ /**
+ * Get this object's name
+ *
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->object->name;
+ }
+
+ public function fetch(): bool
+ {
+ return true;
+ }
+
+ protected function fetchRawCustomvars(): self
+ {
+ if ($this->rawCustomvars !== null) {
+ return $this;
+ }
+
+ $vars = $this->object->customvar->execute();
+
+ $customVars = [];
+ foreach ($vars as $row) {
+ $customVars[$row->name] = $row->value;
+ }
+
+ $this->rawCustomvars = $customVars;
+
+ return $this;
+ }
+
+ protected function fetchRawHostCustomvars(): self
+ {
+ if ($this->rawHostCustomvars !== null) {
+ return $this;
+ }
+
+ $vars = $this->object->host->customvar->execute();
+
+ $customVars = [];
+ foreach ($vars as $row) {
+ $customVars[$row->name] = $row->value;
+ }
+
+ $this->rawHostCustomvars = $customVars;
+
+ return $this;
+ }
+
+ public function fetchComments()
+ {
+ $this->comments = [];
+
+ return $this;
+ }
+
+ public function fetchContactgroups()
+ {
+ $this->contactgroups = [];
+
+ return $this;
+ }
+
+ public function fetchContacts()
+ {
+ $this->contacts = [];
+
+ return $this;
+ }
+
+ public function fetchCustomvars(): self
+ {
+ if ($this->customvars !== null) {
+ return $this;
+ }
+
+ $this->customvars = (new CustomvarFlat())->unflattenVars($this->object->customvar_flat);
+
+ return $this;
+ }
+
+ public function fetchHostVariables()
+ {
+ if (isset($this->hostVariables)) {
+ return $this;
+ }
+
+ $this->hostVariables = [];
+ foreach ($this->object->customvar as $customvar) {
+ $this->hostVariables[strtolower($customvar->name)] = json_decode($customvar->value);
+ }
+
+ return $this;
+ }
+
+ public function fetchServiceVariables()
+ {
+ if (isset($this->serviceVariables)) {
+ return $this;
+ }
+
+ $this->serviceVariables = [];
+ foreach ($this->object->customvar as $customvar) {
+ $this->serviceVariables[strtolower($customvar->name)] = json_decode($customvar->value);
+ }
+
+ return $this;
+ }
+
+ public function fetchDowntimes()
+ {
+ $this->downtimes = [];
+
+ return $this;
+ }
+
+ public function fetchEventhistory()
+ {
+ $this->eventhistory = [];
+
+ return $this;
+ }
+
+ public function fetchHostgroups()
+ {
+ if ($this->type === self::TYPE_HOST) {
+ $hostname = $this->object->name;
+ $hostgroupQuery = clone $this->object->hostgroup;
+ } else {
+ $hostname = $this->object->host->name;
+ $hostgroupQuery = clone $this->object->host->hostgroup;
+ }
+
+ $hostgroupQuery
+ ->columns(['name', 'display_name'])
+ ->filter(Filter::equal('host.name', $hostname));
+
+ /** @var Query $hostgroupQuery */
+ $this->hostgroups = [];
+ foreach ($hostgroupQuery as $hostgroup) {
+ $this->hostgroups[$hostgroup->name] = $hostgroup->display_name;
+ }
+
+ return $this;
+ }
+
+ public function fetchServicegroups()
+ {
+ if ($this->type === self::TYPE_HOST) {
+ $hostname = $this->object->name;
+ $query = Servicegroup::on($this->getDb());
+ } else {
+ $hostname = $this->object->host->name;
+ $query = (clone $this->object->servicegroup);
+ }
+
+ $query
+ ->columns(['name', 'display_name'])
+ ->filter(Filter::equal('host.name', $hostname));
+
+ if ($this->type === self::TYPE_SERVICE) {
+ $query->filter(Filter::equal('service.name', $this->object->name));
+ }
+
+ $this->servicegroups = [];
+ foreach ($query as $serviceGroup) {
+ $this->servicegroups[$serviceGroup->name] = $serviceGroup->display_name;
+ }
+
+ return $this;
+ }
+
+ public function fetchStats()
+ {
+ $query = ServicestateSummary::on($this->getDb());
+
+ if ($this->type === self::TYPE_HOST) {
+ $query->filter(Filter::equal('host.name', $this->object->name));
+ } else {
+ $query->filter(Filter::all(
+ Filter::equal('host.name', $this->object->host->name),
+ Filter::equal('service.name', $this->object->name)
+ ));
+ }
+
+ $result = $query->first();
+
+ $this->stats = (object) [
+ 'services_total' => $result->services_total,
+ 'services_ok' => $result->services_ok,
+ 'services_critical' => $result->services_critical_handled + $result->services_critical_unhandled,
+ 'services_critical_unhandled' => $result->services_critical_unhandled,
+ 'services_critical_handled' => $result->services_critical_handled,
+ 'services_warning' => $result->services_warning_handled + $result->services_warning_unhandled,
+ 'services_warning_unhandled' => $result->services_warning_unhandled,
+ 'services_warning_handled' => $result->services_warning_handled,
+ 'services_unknown' => $result->services_unknown_handled + $result->services_unknown_unhandled,
+ 'services_unknown_unhandled' => $result->services_unknown_unhandled,
+ 'services_unknown_handled' => $result->services_unknown_handled,
+ 'services_pending' => $result->services_pending
+ ];
+
+ return $this;
+ }
+
+ public function __get($name)
+ {
+ if (property_exists($this, $name)) {
+ if ($this->$name === null) {
+ $fetchMethod = 'fetch' . ucfirst($name);
+ $this->$fetchMethod();
+ }
+
+ return $this->$name;
+ }
+
+ if (preg_match('/^_(host|service)_(.+)/i', $name, $matches)) {
+ switch (strtolower($matches[1])) {
+ case $this->type:
+ $customvars = $this->fetchRawCustomvars()->rawCustomvars;
+ break;
+ case self::TYPE_HOST:
+ $customvars = $this->fetchRawHostCustomvars()->rawHostCustomvars;
+ break;
+ case self::TYPE_SERVICE:
+ throw new LogicException('Cannot fetch service custom variables for non-service objects');
+ }
+
+ $variableName = strtolower($matches[2]);
+ if (isset($customvars[$variableName])) {
+ return $customvars[$variableName];
+ }
+
+ return null; // Unknown custom variables MUST NOT throw an error
+ }
+
+ if (! array_key_exists($name, $this->legacyColumns) && ! $this->object->hasProperty($name)) {
+ if (isset($this->customvars[$name])) {
+ return $this->customvars[$name];
+ }
+
+ if (substr($name, 0, strlen($this->prefix)) !== $this->prefix) {
+ $name = $this->prefix . $name;
+ }
+ }
+
+ if (array_key_exists($name, $this->legacyColumns)) {
+ $opts = $this->legacyColumns[$name];
+ if ($opts === null) {
+ return null;
+ }
+
+ $path = $opts['path'];
+ $value = null;
+
+ if (! empty($path)) {
+ $value = $this->object;
+
+ do {
+ $col = array_shift($path);
+ $value = $value->$col;
+ } while (! empty($path) && $value !== null);
+ }
+
+ if (isset($opts['type'])) {
+ $method = 'get' . ucfirst($opts['type']) . 'Type';
+ $value = $this->$method($value);
+ }
+
+ return $value;
+ }
+
+ return $this->object->$name;
+ }
+
+ public function __isset($name)
+ {
+ if (property_exists($this, $name)) {
+ return isset($this->$name);
+ }
+
+ if (isset($this->legacyColumns[$name]) || isset($this->object->$name)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @throws NotImplementedError Don't use!
+ */
+ protected function getDataView()
+ {
+ throw new NotImplementedError('getDataView() is not supported');
+ }
+
+ /**
+ * Get the bool type of the given value as an int
+ *
+ * @param bool|string $value
+ *
+ * @return ?int
+ */
+ private function getBoolType($value)
+ {
+ switch ($value) {
+ case false:
+ return 0;
+ case true:
+ return 1;
+ case 'sticky':
+ return 2;
+ }
+ }
+}