Skip to content

Commit

Permalink
feature/icingadb-support-for-monitoring-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
moreamazingnick committed Jan 23, 2024
1 parent 23340c5 commit fe7b534
Show file tree
Hide file tree
Showing 5 changed files with 326 additions and 26 deletions.
120 changes: 120 additions & 0 deletions library/Vspheredb/IcingadbIntegration/IcingadbObjectFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace Icinga\Module\Vspheredb\IcingadbIntegration;

use Icinga\Exception\InvalidPropertyException;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Icingadb\Model\Host;
use Icinga\Module\Vspheredb\Db;
use Icinga\Module\Vspheredb\Db\CheckRelatedLookup;
use Icinga\Module\Vspheredb\DbObject\HostSystem;
use Icinga\Module\Vspheredb\DbObject\VirtualMachine;
use ipl\Stdlib\Filter;

class IcingadbObjectFinder
{
/** @var Db */
protected $db;
/** @var CheckRelatedLookup */
protected $lookup;
/** @var array */
protected $connections;

public function __construct(Db $db)
{
$this->db = $db;
$this->lookup = new CheckRelatedLookup($this->db);
$this->connections = $this->fetchConnections();
}

/**
* @param Host $object
* @return HostSystem|VirtualMachine|null
*/
public function find(Host $object)
{
if (! $object instanceof Host) {
return null;
}

foreach ($this->connections as $row) {
try {
$filter = $this->filterFromRow($object, 'host', $row);
if ($filter && $host = $this->loadOptionalObject('HostSystem', $filter)) {
return $host;
}
$filter = $this->filterFromRow($object, 'vm', $row);
if ($filter && $vm = $this->loadOptionalObject('VirtualMachine', $filter)) {
return $vm;
}
} catch (InvalidPropertyException $e) {
// Shows problems when accessing MonitoredObjectProperties
continue;
}
}

return null;
}

/**
* @param string $type
* @param array $filter
* @return HostSystem|VirtualMachine|null
*/
protected function loadOptionalObject($type, $filter)
{
try {
$object = $this->lookup->findOneBy($type, $filter);
assert($object instanceof HostSystem || $object instanceof VirtualMachine);
return $object;
} catch (NotFoundError $e) {
return null;
}
}

/**
* @param Host $object
* @param string $prefix
* @param \stdClass $row
* @return array|null
*/
protected function filterFromRow(Host $object, $prefix, $row)
{
$filter = [];
$filterPrefix = $prefix === 'vm' ? 'virtual_machine' : 'host_system';
if ($row->vcenter_uuid !== null) {
$filter[$filterPrefix . '.vcenter_uuid'] = $row->vcenter_uuid;
}
$monPrefix = $prefix === 'vm' ? 'vm_host' : 'host';
$monProperty = $row->{"monitoring_{$monPrefix}_property"};
if ($monProperty === null) {
return null;
}

if (preg_match('/^vars./', $monProperty)) {
$varName = substr($monProperty, 5);
$var = $object->customvar->filter(Filter::equal('name', $varName))->first();
if ($var != null) {
$value = trim($var->value,'"');
} else {
$value = null;
}
} else {
$value = $object->{$monProperty};
}

if ($value === null) {
return null;
}
$filter[$row->{"{$prefix}_property"}] = $value;

return $filter;
}

protected function fetchConnections()
{
return $this->db->getDbAdapter()->fetchAll(
$this->db->getDbAdapter()->select()->from('monitoring_connection')->where('source_type = ?','icingadb')->order('priority DESC')
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ protected function filterFromRow(MonitoredObject $object, $prefix, $row)
protected function fetchConnections()
{
return $this->db->getDbAdapter()->fetchAll(
$this->db->getDbAdapter()->select()->from('monitoring_connection')->order('priority DESC')
$this->db->getDbAdapter()->select()->from('monitoring_connection')->where('source_type = ?','ido')->order('priority DESC')
);
}
}
105 changes: 105 additions & 0 deletions library/Vspheredb/ProvidedHook/Icingadb/HostDetailExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace Icinga\Module\Vspheredb\ProvidedHook\Icingadb;

use Icinga\Module\Icingadb\Hook\HostDetailExtensionHook;
use Icinga\Module\Icingadb\Model\Host;
use Icinga\Module\Monitoring\Object\MonitoredObject;
use Icinga\Module\Vspheredb\Db;
use Icinga\Module\Vspheredb\DbObject\HostQuickStats;
use Icinga\Module\Vspheredb\DbObject\HostSystem;
use Icinga\Module\Vspheredb\DbObject\VirtualMachine;
use Icinga\Module\Vspheredb\DbObject\VmQuickStats;
use Icinga\Module\Vspheredb\IcingadbIntegration\IcingadbObjectFinder;
use Icinga\Module\Vspheredb\MonitoringIntegration\MonitoredObjectFinder;
use Icinga\Module\Vspheredb\Util;
use Icinga\Module\Vspheredb\Web\Widget\CpuAbsoluteUsage;
use Icinga\Module\Vspheredb\Web\Widget\MemoryUsage;
use ipl\Html\Html;
use gipfl\IcingaWeb2\Link;
use ipl\Html\ValidHtml;

class HostDetailExtension extends HostDetailExtensionHook
{
/** @var IcingadbObjectFinder */
protected $finder;

public function init()
{
$this->finder = new IcingadbObjectFinder(Db::newConfiguredInstance());
}

public function getHtmlForObject(Host $object) :ValidHtml
{

$vObject = $this->finder->find($object);
if ($vObject instanceof HostSystem) {
$container = $this->container();
$container->add($this->renderHostSystem($vObject, $object));
return $container;
}
if ($vObject instanceof VirtualMachine) {
$container = $this->container();
$container->add($this->renderVirtualMachine($vObject, $object));
return $container;
}

return Html::tag('a');
}

protected function container()
{
return Html::tag('div', ['class' => [
'icinga-module',
'module-vspheredb',
'vspheredb-monitoring-integration'
]]);
}

protected function renderHostSystem(HostSystem $host, Host $object)
{
$stats = HostQuickStats::loadFor($host);
$cpu = new CpuAbsoluteUsage($stats->get('overall_cpu_usage'), $host->get('hardware_cpu_cores'));
$mem = new MemoryUsage($stats->get('overall_memory_usage_mb'), $host->get('hardware_memory_size_mb'));

return [
Html::tag('h2', null, $this->linkToObject($host, $object)),
Html::tag('div', ['class' => 'monitoring-integration-details'])->add([$mem, $cpu]),
];
}

protected function renderVirtualMachine(VirtualMachine $vm, Host $object)
{
$stats = VmQuickStats::loadFor($vm);
$cpu = new CpuAbsoluteUsage($stats->get('overall_cpu_usage')); // $vm->get('hardware_numcpu')
$mem = new MemoryUsage(
$stats->get('guest_memory_usage_mb'),
$vm->get('hardware_memorymb'),
$stats->get('host_memory_usage_mb')
);

return [
Html::tag('h2', null, $this->linkToObject($vm, $object)),
Html::tag('div', ['class' => 'monitoring-integration-details'])->add([$mem, $cpu]),
];
}

protected function linkToObject($vObject, Host $object)
{
if ($vObject instanceof HostSystem) {
$label = mt('vspheredb', 'ESXi Host: %s');
$url = 'vspheredb/host';
} elseif ($vObject instanceof VirtualMachine) {
$label = mt('vspheredb', 'Virtual Machine: %s');
$url = 'vspheredb/vm';
} else {
throw new \RuntimeException(sprintf('Unable to link to %s', get_class($vObject)));
}

return Link::create(
sprintf($label, $vObject->object()->get('object_name')),
$url,
['uuid' => Util::niceUuid($vObject->uuid), 'monitoringObject' => $object->name]
);
}
}
Loading

0 comments on commit fe7b534

Please sign in to comment.