mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-31 01:34:12 +02:00
HostApplyMatches: resolve services and -sets...
...for Icinga v1.x refs #13049
This commit is contained in:
parent
87fe623d11
commit
ba7d350a8c
109
library/Director/Objects/HostApplyMatches.php
Normal file
109
library/Director/Objects/HostApplyMatches.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
|
use Icinga\Application\Benchmark;
|
||||||
|
use Icinga\Data\Filter\Filter;
|
||||||
|
use Icinga\Data\Filter\FilterExpression;
|
||||||
|
use Icinga\Module\Director\Db;
|
||||||
|
use Icinga\Module\Director\Db\Cache\PrefetchCache;
|
||||||
|
|
||||||
|
class HostApplyMatches
|
||||||
|
{
|
||||||
|
protected static $flatObjects;
|
||||||
|
|
||||||
|
protected static $columnMap = array(
|
||||||
|
'name' => 'object_name'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Filter $filter
|
||||||
|
* @param Db $db
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function forFilter(Filter $filter, Db $db)
|
||||||
|
{
|
||||||
|
$result = array();
|
||||||
|
Benchmark::measure(sprintf('Starting Filter %s', $filter));
|
||||||
|
$filter = clone($filter);
|
||||||
|
static::fixFilterColumns($filter);
|
||||||
|
foreach (static::flatObjects($db) as $object) {
|
||||||
|
if ($filter->matches($object)) {
|
||||||
|
$name = $object->object_name;
|
||||||
|
$result[] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Benchmark::measure(sprintf('Got %d results for %s', count($result), $filter));
|
||||||
|
|
||||||
|
return array_values($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function flatObjects(Db $db)
|
||||||
|
{
|
||||||
|
if (self::$flatObjects === null) {
|
||||||
|
self::$flatObjects = static::fetchFlatObjects($db);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$flatObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function fetchFlatObjects(Db $db)
|
||||||
|
{
|
||||||
|
Benchmark::measure('HostApplyMatches: prefetching');
|
||||||
|
PrefetchCache::initialize($db);
|
||||||
|
$all = IcingaHost::prefetchAll($db);
|
||||||
|
IcingaZone::prefetchAll($db);
|
||||||
|
IcingaCommand::prefetchAll($db);
|
||||||
|
Benchmark::measure('HostApplyMatches: preparing flat objects');
|
||||||
|
|
||||||
|
$objects = array();
|
||||||
|
foreach ($all as $host) {
|
||||||
|
if ($host->isTemplate()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$object = $host->toPlainObject(true);
|
||||||
|
static::flattenVars($object);
|
||||||
|
$objects[$host->getObjectName()] = $object;
|
||||||
|
}
|
||||||
|
Benchmark::measure('HostApplyMatches: cache ready');
|
||||||
|
|
||||||
|
return $objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function fixFilterColumns(Filter $filter)
|
||||||
|
{
|
||||||
|
if ($filter->isExpression()) {
|
||||||
|
/** @var FilterExpression $filter */
|
||||||
|
$col = $filter->getColumn();
|
||||||
|
if (substr($col, 0, 5) === 'host.') {
|
||||||
|
$filter->setColumn($col = substr($col, 5));
|
||||||
|
}
|
||||||
|
if (array_key_exists($col, self::$columnMap)) {
|
||||||
|
$filter->setColumn(self::$columnMap[$col]);
|
||||||
|
}
|
||||||
|
$filter->setExpression(json_decode($filter->getExpression()));
|
||||||
|
} else {
|
||||||
|
foreach ($filter->filters() as $sub) {
|
||||||
|
static::fixFilterColumns($sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function flattenVars(& $object, $key = 'vars')
|
||||||
|
{
|
||||||
|
if (property_exists($object, 'vars')) {
|
||||||
|
foreach ($object->vars as $k => $v) {
|
||||||
|
if (is_object($v)) {
|
||||||
|
static::flattenVars($v, $k);
|
||||||
|
}
|
||||||
|
$object->{$key . '.' . $k} = $v;
|
||||||
|
}
|
||||||
|
unset($object->vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Objects;
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\ProgrammingError;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Data\PropertiesFilter;
|
use Icinga\Module\Director\Data\PropertiesFilter;
|
||||||
@ -174,8 +175,47 @@ class IcingaService extends IcingaObject
|
|||||||
return $this->renderRelationProperty('host', $this->host_id, 'host_name');
|
return $this->renderRelationProperty('host', $this->host_id, 'host_name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function toLegacyConfigString()
|
||||||
|
{
|
||||||
|
if ($this->get('assign_filter')) {
|
||||||
|
return $this->renderLegacyResolvedAssignFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
$str = parent::toLegacyConfigString();
|
||||||
|
|
||||||
|
if (! $this->isDisabled() && $this->host_id && $this->getRelated('host')->isDisabled()) {
|
||||||
|
return
|
||||||
|
"# --- This services host has been disabled ---\n"
|
||||||
|
. preg_replace('~^~m', '# ', trim($str))
|
||||||
|
. "\n\n";
|
||||||
|
} else {
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderLegacyResolvedAssignFilter()
|
||||||
|
{
|
||||||
|
$str = '';
|
||||||
|
$hosts = HostApplyMatches::forFilter(
|
||||||
|
Filter::fromQueryString($this->get('assign_filter')),
|
||||||
|
$this->getConnection()
|
||||||
|
);
|
||||||
|
$this->object_type = 'object';
|
||||||
|
$this->assign_filter = null;
|
||||||
|
|
||||||
|
foreach ($hosts as $hostname) {
|
||||||
|
$this->host = $hostname;
|
||||||
|
$str .= $this->toLegacyConfigString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
public function toConfigString()
|
public function toConfigString()
|
||||||
{
|
{
|
||||||
|
if ($this->get('service_set_id')) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
$str = parent::toConfigString();
|
$str = parent::toConfigString();
|
||||||
|
|
||||||
if (! $this->isDisabled() && $this->host_id && $this->getRelated('host')->isDisabled()) {
|
if (! $this->isDisabled() && $this->host_id && $this->getRelated('host')->isDisabled()) {
|
||||||
@ -282,6 +322,11 @@ class IcingaService extends IcingaObject
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderService_set()
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
public function renderUse_var_overrides()
|
public function renderUse_var_overrides()
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Objects;
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\ProgrammingError;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
@ -45,11 +46,11 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return IcingaService
|
* @return IcingaService[]
|
||||||
*/
|
*/
|
||||||
public function getServiceObjects()
|
public function getServiceObjects()
|
||||||
{
|
{
|
||||||
if ($this->host_id) {
|
if ($this->get('host_id')) {
|
||||||
$imports = $this->imports()->getObjects();
|
$imports = $this->imports()->getObjects();
|
||||||
if (empty($imports)) {
|
if (empty($imports)) {
|
||||||
return array();
|
return array();
|
||||||
@ -62,7 +63,7 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
|
|
||||||
protected function getServiceObjectsForSet(IcingaServiceSet $set)
|
protected function getServiceObjectsForSet(IcingaServiceSet $set)
|
||||||
{
|
{
|
||||||
if ($set->id === null) {
|
if ($set->get('id') === null) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
$db = $this->getDb();
|
$db = $this->getDb();
|
||||||
$ids = $db->fetchCol(
|
$ids = $db->fetchCol(
|
||||||
$db->select()->from('icinga_service', 'id')
|
$db->select()->from('icinga_service', 'id')
|
||||||
->where('service_set_id = ?', $set->id)
|
->where('service_set_id = ?', $set->get('id'))
|
||||||
);
|
);
|
||||||
|
|
||||||
$services = array();
|
$services = array();
|
||||||
@ -80,7 +81,7 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
'object_type' => 'template'
|
'object_type' => 'template'
|
||||||
), $connection);
|
), $connection);
|
||||||
|
|
||||||
$services[$service->object_name] = $service;
|
$services[$service->getObjectName()] = $service;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $services;
|
return $services;
|
||||||
@ -88,12 +89,13 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
|
|
||||||
public function renderToConfig(IcingaConfig $config)
|
public function renderToConfig(IcingaConfig $config)
|
||||||
{
|
{
|
||||||
if ($this->assign_filter === null && $this->isTemplate()) {
|
if ($this->get('assign_filter') === null && $this->isTemplate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($config->isLegacy()) {
|
if ($config->isLegacy()) {
|
||||||
return $this->renderToLegacyConfig($config);
|
$this->renderToLegacyConfig($config);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = $this->getConfigFileWithHeader($config);
|
$file = $this->getConfigFileWithHeader($config);
|
||||||
@ -103,19 +105,18 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
// eventually clone them beforehand to not get into trouble with caches
|
// eventually clone them beforehand to not get into trouble with caches
|
||||||
// figure out whether we might need a zone property
|
// figure out whether we might need a zone property
|
||||||
foreach ($this->getServiceObjects() as $service) {
|
foreach ($this->getServiceObjects() as $service) {
|
||||||
// TODO: make them REAL applies
|
if ($filter = $this->get('assign_filter')) {
|
||||||
if ($this->assign_filter) {
|
$service->set('object_type', 'apply');
|
||||||
$service->object_type = 'apply';
|
$service->set('assign_filter', $filter);
|
||||||
$service->assign_filter = $this->assign_filter;
|
} elseif ($hostId = $this->get('host_id')) {
|
||||||
|
$service->set('object_type', 'object');
|
||||||
|
$service->host_id = $this->host_id;
|
||||||
} else {
|
} else {
|
||||||
$service->object_type = $this->object_type;
|
// Service set template without assign filter or host
|
||||||
if ($this->isApplyRule()) {
|
continue;
|
||||||
$service->assign_filter = $this->assign_filter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$service->vars = $this->vars;
|
$this->copyVarsToService($service);
|
||||||
$service->host_id = $this->host_id;
|
|
||||||
$file->addObject($service);
|
$file->addObject($service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,20 +142,26 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
return sprintf($comment, $this->object_name);
|
return sprintf($comment, $this->object_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderToLegacyConfig(IcingaConfig $config)
|
protected function copyVarsToService(IcingaService $service)
|
||||||
{
|
{
|
||||||
if ($this->isTemplate()) {
|
$serviceVars = $service->vars();
|
||||||
return;
|
|
||||||
|
foreach ($this->vars() as $k => $var) {
|
||||||
|
$serviceVars->$k = $var;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isApplyRule()) {
|
return $this;
|
||||||
// Not yet
|
}
|
||||||
|
|
||||||
|
public function renderToLegacyConfig(IcingaConfig $config)
|
||||||
|
{
|
||||||
|
if ($this->assign_filter === null && $this->isTemplate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// evaluate my assign rules once, get related hosts
|
// evaluate my assign rules once, get related hosts
|
||||||
// Loop over all services belonging to this set
|
// Loop over all services belonging to this set
|
||||||
// generate every service with host_name host1,host2...
|
// generate every service with host_name host1,host2... -> not yet. And Zones?
|
||||||
|
|
||||||
$file = $config->configFile(
|
$file = $config->configFile(
|
||||||
// TODO: zones.d?
|
// TODO: zones.d?
|
||||||
@ -162,21 +169,39 @@ class IcingaServiceSet extends IcingaObject
|
|||||||
);
|
);
|
||||||
|
|
||||||
$file->prepend($this->getConfigHeaderComment($config));
|
$file->prepend($this->getConfigHeaderComment($config));
|
||||||
|
$conn = $this->getConnection();
|
||||||
|
|
||||||
foreach ($this->getServiceObjects() as $service) {
|
// Delegating this to the service would look, but this way it's faster
|
||||||
$service->object_type = 'object';
|
if ($filter = $this->get('assign_filter')) {
|
||||||
$service->host_id = $this->host_id;
|
$filter = Filter::fromQueryString($filter);
|
||||||
$service->vars = $this->vars;
|
$hosts = HostApplyMatches::forFilter($filter, $conn);
|
||||||
$file->addLegacyObject($service);
|
foreach ($this->getServiceObjects() as $service) {
|
||||||
|
$service->set('object_type', 'object');
|
||||||
|
$this->copyVarsToService($service);
|
||||||
|
|
||||||
|
foreach ($hosts as $hostname) {
|
||||||
|
$service->host = $hostname;
|
||||||
|
$file->addLegacyObject($service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($this->getServiceObjects() as $service) {
|
||||||
|
$service->set('object_type', 'object');
|
||||||
|
$service->set('host_id', $this->get('host_id'));
|
||||||
|
foreach ($this->vars() as $k => $var) {
|
||||||
|
$service->$k = $var;
|
||||||
|
}
|
||||||
|
$file->addLegacyObject($service);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRenderingZone(IcingaConfig $config = null)
|
public function getRenderingZone(IcingaConfig $config = null)
|
||||||
{
|
{
|
||||||
if ($this->host_id === null) {
|
if ($this->get('host_id') === null) {
|
||||||
return $this->connection->getDefaultGlobalZoneName();
|
return $this->connection->getDefaultGlobalZoneName();
|
||||||
} else {
|
} else {
|
||||||
$host = $this->getRelatedObject('host', $this->host_id);
|
$host = $this->getRelatedObject('host', $this->get('host_id'));
|
||||||
return $host->getRenderingZone($config);
|
return $host->getRenderingZone($config);
|
||||||
}
|
}
|
||||||
return $zone;
|
return $zone;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user