summaryrefslogtreecommitdiffstats
path: root/library/Cube/IcingaDb/CustomVariableDimension.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Cube/IcingaDb/CustomVariableDimension.php')
-rw-r--r--library/Cube/IcingaDb/CustomVariableDimension.php166
1 files changed, 166 insertions, 0 deletions
diff --git a/library/Cube/IcingaDb/CustomVariableDimension.php b/library/Cube/IcingaDb/CustomVariableDimension.php
new file mode 100644
index 0000000..34a395c
--- /dev/null
+++ b/library/Cube/IcingaDb/CustomVariableDimension.php
@@ -0,0 +1,166 @@
+<?php
+
+// Icinga Web 2 Cube Module | (c) 2022 Icinga GmbH | GPLv2
+
+namespace Icinga\Module\Cube\IcingaDb;
+
+use Icinga\Module\Cube\Cube;
+use Icinga\Module\Cube\Dimension;
+use Icinga\Module\Icingadb\Common\Auth;
+use Icinga\Module\Icingadb\Model\CustomvarFlat;
+use Icinga\Module\Icingadb\Model\Service;
+use ipl\Sql\Expression;
+use ipl\Stdlib\Filter;
+
+class CustomVariableDimension implements Dimension
+{
+ use Auth;
+
+ /** @var string Prefix for host custom variable */
+ public const HOST_PREFIX = 'host.vars.';
+
+ /** @var string Prefix for service custom variable */
+ public const SERVICE_PREFIX = 'service.vars.';
+
+ /** @var ?string variable source name */
+ protected $sourceName;
+
+ /** @var ?string Variable name without prefix */
+ protected $varName;
+
+ /** @var string Variable name with prefix */
+ protected $name;
+
+ protected $label;
+
+ protected $wantNull = false;
+
+ public function __construct($name)
+ {
+ if (preg_match('/^(host|service)\.vars\.(.*)/', $name, $matches)) {
+ $this->sourceName = $matches[1];
+ $this->varName = $matches[2];
+ }
+
+ $this->name = $name;
+ }
+
+ /**
+ * Get the variable name without prefix
+ *
+ * @return string
+ */
+ public function getVarName(): string
+ {
+ return $this->varName ?? $this->getName();
+ }
+
+ /**
+ * Get the variable source name
+ *
+ * @return ?string
+ */
+ public function getSourceName(): ?string
+ {
+ return $this->sourceName;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getLabel()
+ {
+ return $this->label ?: $this->getName();
+ }
+
+ public function setLabel($label)
+ {
+ $this->label = $label;
+
+ return $this;
+ }
+
+ public function addLabel($label)
+ {
+ if ($this->label === null) {
+ $this->setLabel($label);
+ } else {
+ $this->label .= ' & ' . $label;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Define whether null values should be shown
+ *
+ * @param bool $wantNull
+ * @return $this
+ */
+ public function wantNull($wantNull = true)
+ {
+ $this->wantNull = $wantNull;
+
+ return $this;
+ }
+
+ /**
+ * @param IcingaDbCube $cube
+ * @return Expression|string
+ */
+ public function getColumnExpression(Cube $cube)
+ {
+ $expression = $cube->getDb()->quoteIdentifier([$this->createCustomVarAlias(), 'flatvalue']);
+
+ if ($this->wantNull) {
+ return new Expression("COALESCE($expression, '-')");
+ }
+
+ return $expression;
+ }
+
+ public function addToCube(Cube $cube)
+ {
+ /** @var IcingaDbCube $cube */
+ $innerQuery = $cube->innerQuery();
+ $sourceTable = $this->getSourceName() ?? $innerQuery->getModel()->getTableName();
+
+ $subQuery = $innerQuery->createSubQuery(new CustomvarFlat(), $sourceTable . '.vars');
+ $subQuery->getSelectBase()->resetWhere(); // The link to the outer query is the ON condition
+ $subQuery->columns(['flatvalue', 'object_id' => $sourceTable . '.id']);
+ $subQuery->filter(Filter::like('flatname', $this->getVarName()));
+
+ // Values might not be unique (wildcard dimensions)
+ $subQueryModelAlias = $subQuery->getResolver()->getAlias($subQuery->getModel());
+ $subQuery->getSelectBase()->groupBy([
+ $subQueryModelAlias . '.flatname', // Required by postgres, if there are any custom variable protections
+ $subQueryModelAlias . '.flatvalue',
+ 'object_id'
+ ]);
+
+ $this->applyRestrictions($subQuery);
+
+ $subQueryAlias = $cube->getDb()->quoteIdentifier([$this->createCustomVarAlias()]);
+ $innerQuery->getSelectBase()->groupBy($subQueryAlias . '.flatvalue');
+
+ $sourceIdPath = '.id';
+ if ($innerQuery->getModel() instanceof Service && $sourceTable === 'host') {
+ $sourceIdPath = '.host_id';
+ }
+
+ $innerQuery->getSelectBase()->join(
+ [$subQueryAlias => $subQuery->assembleSelect()],
+ [
+ $subQueryAlias . '.object_id = '
+ . $innerQuery->getResolver()->getAlias($innerQuery->getModel()) . $sourceIdPath
+ ]
+ );
+ }
+
+ protected function createCustomVarAlias(): string
+ {
+ return implode('_', ['c', $this->getSourceName(), $this->getVarName()]);
+ }
+}