Lots of files: make IDE users happy

This commit is contained in:
Thomas Gelf 2016-11-01 18:28:36 +01:00
parent 1a02543321
commit ee0def7d2b
92 changed files with 775 additions and 678 deletions

View File

@ -4,6 +4,8 @@ namespace Icinga\Module\Director\Clicommands;
use Icinga\Application\Benchmark;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filter\FilterChain;
use Icinga\Data\Filter\FilterExpression;
use Icinga\Module\Director\Cli\Command;
use Icinga\Module\Director\Objects\IcingaHost;
use Icinga\Module\Director\Objects\IcingaHostVar;
@ -14,6 +16,7 @@ class BenchmarkCommand extends Command
{
$flat = array();
/** @var FilterChain|FilterExpression $filter */
$filter = Filter::fromQueryString(
// 'object_name=*ic*2*&object_type=object'
'vars.bpconfig=*'
@ -23,9 +26,9 @@ class BenchmarkCommand extends Command
Benchmark::measure('db done');
foreach ($objs as $host) {
$flat[$host->id] = (object) array();
$flat[$host->get('id')] = (object) array();
foreach ($host->getProperties() as $k => $v) {
$flat[$host->id]->$k = $v;
$flat[$host->get('id')]->$k = $v;
}
}
Benchmark::measure('objects ready');
@ -33,11 +36,11 @@ class BenchmarkCommand extends Command
$vars = IcingaHostVar::loadAll($this->db());
Benchmark::measure('vars loaded');
foreach ($vars as $var) {
if (! array_key_exists($var->host_id, $flat)) {
if (! array_key_exists($var->get('host_id'), $flat)) {
// Templates?
continue;
}
$flat[$var->host_id]->{'vars.' . $var->varname} = $var->varvalue;
$flat[$var->get('host_id')]->{'vars.' . $var->get('varname')} = $var->get('varvalue');
}
Benchmark::measure('vars done');
@ -46,8 +49,5 @@ class BenchmarkCommand extends Command
echo $host->object_name . "\n";
}
}
return;
Benchmark::measure('all done');
}
}

View File

@ -55,6 +55,7 @@ class ConfigCommand extends Command
$longestTime = 0;
$longestQuery = null;
/** @var \Zend_Db_Profiler_Query $query */
foreach ($profiler->getQueryProfiles() as $query) {
echo $query->getQuery() . "\n";
if ($query->getElapsedSecs() > $longestTime) {

View File

@ -2,7 +2,6 @@
namespace Icinga\Module\Director\Clicommands;
use Icinga\Application\Benchmark;
use Icinga\Exception\MissingParameterException;
use Icinga\Module\Director\Cli\Command;
use Icinga\Module\Director\Db\Housekeeping;

View File

@ -5,12 +5,6 @@ namespace Icinga\Module\Director\Clicommands;
use Icinga\Module\Director\Cli\Command;
use Icinga\Module\Director\Job\JobRunner;
use Icinga\Module\Director\Objects\DirectorJob;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Objects\SyncRule;
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
use Icinga\Module\Director\Import\Import;
use Icinga\Module\Director\Import\Sync;
use Icinga\Application\Benchmark;
use Icinga\Application\Logger;
use Exception;

View File

@ -29,7 +29,7 @@ class ServiceCommand extends ObjectCommand
if ($host = $this->params->get('host')) {
return array(
'object_name' => $name,
'host_id' => IcingaHost::load($host, $this->db())->id,
'host_id' => IcingaHost::load($host, $this->db())->get('id'),
);
} else {
return array(

View File

@ -8,6 +8,7 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class ApplyMigrationsForm extends QuickForm
{
/** @var Migrations */
protected $migrations;
public function setup()

View File

@ -1,63 +0,0 @@
<?php
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Web\Form\QuickSubForm;
class AssignListSubForm extends QuickSubForm
{
protected $object;
public function setObject($object)
{
$this->object = $object;
return $this;
}
public function setup()
{
$idx = -1;
if ($this->object && $this->object->supportsAssignments()) {
foreach ($this->object->assignments()->getValues() as $values) {
$idx++;
$sub = $this->loadForm('assignmentSub');
$sub->setObject($this->object);
$sub->setup();
$sub->populate($values);
$this->addSubForm($sub, $idx);
}
}
$idx++;
$sub = $this->loadForm('assignmentSub');
$sub->setObject($this->object);
$sub->setup();
$this->addSubForm($sub, $idx);
$this->addElement('submit', 'addmore', array(
'label' => $this->translate('Add more'),
'class' => 'link-button icon-plus',
'ignore' => true,
));
$this->getElement('addmore')->setDecorators(array('ViewHelper'));
}
public function loadDefaultDecorators()
{
$this->setDecorators(array(
'FormElements',
array('HtmlTag', array(
'tag' => 'ul',
'class' => 'assign-rule required'
)),
array('Fieldset', array(
'legend' => 'Assignment rules',
)),
));
return $this;
}
}

View File

@ -1,55 +0,0 @@
<?php
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Objects\IcingaHost;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Web\Form\QuickSubForm;
class AssignmentSubForm extends QuickSubForm
{
protected $object;
// @codingStandardsIgnoreStart
protected $_disableLoadDefaultDecorators = true;
// @codingStandardsIgnoreEnd
public function setup()
{
$this->addElement('select', 'assign_type', array(
'multiOptions' => array(
'assign' => 'assign where',
'ignore' => 'ignore where',
),
'class' => 'assign-type',
'value' => 'assign'
));
$this->addElement('dataFilter', 'filter_string', array(
'columns' => IcingaHost::enumProperties($this->db)
));
foreach ($this->getElements() as $el) {
$el->setDecorators(array('ViewHelper', 'Errors'));
}
}
public function setObject(IcingaObject $object)
{
$this->object = $object;
return $this;
}
public function loadDefaultDecorators()
{
$this->setDecorators(array(
'FormElements',
array('HtmlTag', array(
'tag' => 'li',
)),
array('FormErrors'),
));
return $this;
}
}

View File

@ -38,7 +38,7 @@ class DeployConfigForm extends QuickForm
$label = $this->translate('There are no pending changes. Deploy anyways');
} else {
$label = sprintf(
$this->translate('Deploy %d pending changes', $activities),
$this->translate('Deploy %d pending changes'),
$activities
);
}
@ -82,7 +82,6 @@ class DeployConfigForm extends QuickForm
$config = IcingaConfig::load(Util::hex2binary($this->checksum), $db);
} else {
$config = IcingaConfig::generate($db);
$checksum = $config->getHexChecksum();
}
$this->api->wipeInactiveStages($db);
@ -90,7 +89,7 @@ class DeployConfigForm extends QuickForm
if ($this->api->dumpConfig($config, $db)) {
if ($isApiRequest) {
die('Api not ready');
return $this->sendJson((object) array('checksum' => $checksum));
// return $this->sendJson((object) array('checksum' => $checksum));
} else {
$this->setSuccessUrl('director/config/deployments');
$this->setSuccessMessage(

View File

@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Forms;
use Icinga\Exception\ConfigurationError;
use Icinga\Module\Director\CustomVariable\CustomVariables;
use Icinga\Module\Director\Hook\DataTypeHook;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Application\Hook;
use Exception;
@ -133,7 +134,7 @@ class DirectorDatafieldForm extends DirectorObjectForm
if ($class && array_key_exists($class, $types)) {
$this->addSettings($class);
}
} elseif ($class = $this->object()->datatype) {
} elseif ($class = $this->object()->get('datatype')) {
$this->addSettings($class);
}
@ -176,6 +177,7 @@ class DirectorDatafieldForm extends DirectorObjectForm
$object = $this->object();
$global = array('varname', 'description', 'caption', 'datatype');
/** @var \Zend_Form_Element $el */
foreach ($this->getElements() as $el) {
if ($el->getIgnore()) {
continue;
@ -214,6 +216,7 @@ class DirectorDatafieldForm extends DirectorObjectForm
{
$hooks = Hook::all('Director\\DataType');
$enum = array(null => '- please choose -');
/** @var DataTypeHook $hook */
foreach ($hooks as $hook) {
$enum[get_class($hook)] = $hook->getName();
}

View File

@ -29,7 +29,7 @@ class DirectorDatalistForm extends DirectorObjectForm
public function onSuccess()
{
$this->object()->owner = self::username();
$this->object()->set('owner', self::username());
parent::onSuccess();
}

View File

@ -7,6 +7,7 @@ use Icinga\Module\Director\Web\Form\DirectorObjectForm;
class DirectorDatalistEntryForm extends DirectorObjectForm
{
/** @var DirectorDatalist */
protected $datalist;
public function setup()
@ -28,10 +29,10 @@ class DirectorDatalistEntryForm extends DirectorObjectForm
)
));
$this->addHidden('list_id', $this->datalist->id);
$this->addHidden('list_id', $this->datalist->get('id'));
$this->addHidden('format', 'string');
if (!$this->isNew()) {
$this->addHidden('entry_name', $this->object->entry_name);
$this->addHidden('entry_name', $this->object->get('entry_name'));
}
$this->addSimpleDisplayGroup(array('entry_name', 'entry_value'), 'entry', array(

View File

@ -2,6 +2,8 @@
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Data\Db\DbObjectWithSettings;
use Icinga\Module\Director\Hook\JobHook;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Web\Hook;
@ -84,8 +86,8 @@ class DirectorJobForm extends DirectorObjectForm
if ($this->hasObject()) {
$value = $this->getSentValue($name);
if ($value === null) {
/** @var DbObjectWithSettings $object */
$object = $this->getObject();
return $object->getSetting($name, $default);
} else {
return $value;
@ -124,9 +126,11 @@ class DirectorJobForm extends DirectorObjectForm
protected function enumJobTypes()
{
/** @var JobHook[] $hooks */
$hooks = Hook::all('Director\\Job');
$enum = array();
foreach ($hooks as $hook) {
$enum[get_class($hook)] = $hook->getName();
}

View File

@ -7,6 +7,7 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class IcingaCloneObjectForm extends QuickForm
{
/** @var IcingaObject */
protected $object;
public function setup()
@ -14,7 +15,7 @@ class IcingaCloneObjectForm extends QuickForm
$this->addElement('text', 'new_object_name', array(
'label' => $this->translate('New name'),
'required' => true,
'value' => $this->object->object_name,
'value' => $this->object->getObjectName(),
));
$this->addElement('select', 'clone_type', array(
@ -28,13 +29,14 @@ class IcingaCloneObjectForm extends QuickForm
$this->submitLabel = sprintf(
$this->translate('Clone "%s"'),
$this->object->object_name
$this->object->getObjectName()
);
}
public function onSuccess()
{
$object = $this->object;
$newname = $this->getValue('new_object_name');
$resolve = $this->getValue('clone_type') === 'flat';
@ -43,7 +45,7 @@ class IcingaCloneObjectForm extends QuickForm
'The %s "%s" has been cloned from "%s"',
$object->getShortTableName(),
$newname,
$object->object_name
$object->getObjectName()
);
$new = $object::fromPlainObject(
@ -58,8 +60,6 @@ class IcingaCloneObjectForm extends QuickForm
);
$this->redirectOnSuccess($msg);
} else {
$this->redirectOnFailure($msg);
}
}

View File

@ -3,11 +3,11 @@
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Objects\IcingaCommand;
use Icinga\Module\Director\Objects\IcingaCommandArgument;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
class IcingaCommandArgumentForm extends DirectorObjectForm
{
/** @var IcingaCommand */
protected $commandObject;
public function setCommandObject(IcingaCommand $object)
@ -19,7 +19,7 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
public function setup()
{
$this->addHidden('command_id', $this->commandObject->id);
$this->addHidden('command_id', $this->commandObject->get('id'));
$this->addElement('text', 'argument_name', array(
'label' => $this->translate('Argument name'),
@ -121,7 +121,7 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
$msg = sprintf(
'%s argument "%s" has been removed',
$this->translate($this->getObjectName()),
$this->translate($this->getObjectShortClassName()),
$object->argument_name
);
@ -140,20 +140,20 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
$object = $this->object();
$cmd = $this->commandObject;
if (! $object->hasBeenLoadedFromDb()) {
if ($object->argument_name === null) {
$object->skip_key = true;
$object->argument_name = $cmd->getNextSkippableKeyName();
if ($object->get('argument_name') === null) {
$object->set('skip_key', true);
$object->set('argument_name', $cmd->getNextSkippableKeyName());
}
}
if ($object->hasBeenModified()) {
$cmd->arguments()->set(
$object->argument_name,
$object->get('argument_name'),
$object
);
$msg = sprintf(
$this->translate('The argument %s has successfully been stored'),
$object->argument_name
$object->get('argument_name')
);
$cmd->store($this->db);
} else {
@ -162,7 +162,7 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
}
$this->setSuccessUrl(
'director/command/arguments',
array('name' => $cmd->object_name)
array('name' => $cmd->getObjectName())
);
$this->redirectOnSuccess($msg);

View File

@ -8,13 +8,14 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class IcingaDeleteObjectForm extends QuickForm
{
/** @var IcingaObject */
protected $object;
public function setup()
{
$this->submitLabel = sprintf(
$this->translate('YES, please delete "%s"'),
$this->object->object_name
$this->object->getObjectName()
);
}
@ -25,13 +26,11 @@ class IcingaDeleteObjectForm extends QuickForm
$msg = sprintf(
'The %s "%s" has been deleted',
$object->getShortTableName(),
$object->object_name
$object->getObjectName()
);
if ($object->delete()) {
$this->redirectOnSuccess($msg);
} else {
$this->redirectOnFailure($msg);
}
}

View File

@ -2,7 +2,6 @@
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Objects\DirectorDatafield;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
class IcingaHostForm extends DirectorObjectForm
@ -11,7 +10,8 @@ class IcingaHostForm extends DirectorObjectForm
{
$this->addObjectTypeElement();
if (! $this->hasObjectType()) {
return $this->groupMainProperties();
$this->groupMainProperties();
return;
}
$this->addElement('text', 'object_name', array(
@ -45,6 +45,9 @@ class IcingaHostForm extends DirectorObjectForm
->setButtons();
}
/**
* @return self
*/
protected function addClusteringElements()
{
if (!$this->isTemplate() && !$this->hasClusterProperties()) {
@ -121,7 +124,7 @@ class IcingaHostForm extends DirectorObjectForm
return false;
}
return $object->zone_id || $object->has_agent;
return $object->get('zone_id') || $object->get('has_agent') === 'y';
}
protected function beforeSuccessfulRedirect()
@ -134,6 +137,9 @@ class IcingaHostForm extends DirectorObjectForm
}
}
/**
* @return self
*/
protected function addGroupsElement()
{
$groups = $this->enumHostgroups();
@ -157,6 +163,9 @@ class IcingaHostForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addAddressElements()
{
if ($this->isTemplate()) {
@ -179,6 +188,9 @@ class IcingaHostForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addDisplayNameElement()
{
if ($this->isTemplate()) {

View File

@ -7,6 +7,7 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class IcingaImportObjectForm extends QuickForm
{
/** @var IcingaObject */
protected $object;
public function setup()
@ -30,17 +31,18 @@ class IcingaImportObjectForm extends QuickForm
public function onSuccess()
{
if ($this->object->set('object_type', 'object')->store()) {
$object = $this->object;
if ($object->set('object_type', 'object')->store()) {
$this->redirectOnSuccess(sprintf(
$this->translate('%s "%s" has been imported"'),
$object->getShortTableName(),
$object->object_name
$object->getObjectName()
));
} else {
$this->redirectOnFailure(sprintf(
$this->addError(sprintf(
$this->translate('Failed to import %s "%s"'),
$object->getShortTableName(),
$object->object_name
$object->getObjectName()
));
}
}

View File

@ -2,7 +2,7 @@
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Web\Form\FormLoader;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Web\Form\IcingaObjectFieldLoader;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Module\Director\Web\Form\QuickForm;
@ -10,10 +10,12 @@ use Zend_Form_Element as ZfElement;
class IcingaMultiEditForm extends DirectorObjectForm
{
/** @var DbObject[] */
private $objects;
private $elementGroupMap;
/** @var QuickForm */
private $relatedForm;
private $propertiesToPick;
@ -41,9 +43,12 @@ class IcingaMultiEditForm extends DirectorObjectForm
$loader->addFieldsToForm($this);
if ($form = $this->relatedForm) {
$form->setDb($object->getConnection())
->setObject($object)
->prepareElements();
if ($form instanceof DirectorObjectForm) {
$form->setDb($object->getConnection())
->setObject($object);
}
$form->prepareElements();
} else {
$this->propertiesToPick = array();
}
@ -54,6 +59,7 @@ class IcingaMultiEditForm extends DirectorObjectForm
}
}
/** @var \Zend_Form_Element $el */
foreach ($this->getElements() as $el) {
$name = $el->getName();
if (substr($name, 0, 4) === 'var_') {
@ -103,7 +109,6 @@ class IcingaMultiEditForm extends DirectorObjectForm
$value = null;
}
$found = false;
foreach ($this->getVariants($property) as $json => $objects) {
if ($valueSum !== sha1($json)) {
continue;
@ -113,7 +118,6 @@ class IcingaMultiEditForm extends DirectorObjectForm
continue;
}
$found = true;
if (substr($property, 0, 4) === 'var_') {
$property = 'vars.' . substr($property, 4);
}
@ -152,18 +156,18 @@ class IcingaMultiEditForm extends DirectorObjectForm
} elseif ($this->relatedForm) {
return $this->stealDisplayGroup($groupName, $this->relatedForm);
}
} else {
return null;
}
return null;
}
protected function stealDisplayGroup($name, $form)
protected function stealDisplayGroup($name, QuickForm $form)
{
if ($group = $this->relatedForm->getDisplayGroup($name)) {
if ($group = $form->getDisplayGroup($name)) {
$group = clone($group);
$group->setElements(array());
$this->_displayGroups[$name] = $group;
$this->_order[$name] = $this->_displayGroups[$name]->getOrder();
$this->_order[$name] = $group->getOrder();
$this->_orderUpdated = true;
return $group;
@ -176,14 +180,15 @@ class IcingaMultiEditForm extends DirectorObjectForm
{
$this->elementGroupMap = array();
if ($form = $this->relatedForm) {
$this->extractFormDisplayGroups($form, true);
$this->extractFormDisplayGroups($form);
}
$this->extractFormDisplayGroups($this);
}
protected function extractFormDisplayGroups($form, $clone = false)
protected function extractFormDisplayGroups(QuickForm $form)
{
/** @var \Zend_Form_DisplayGroup $group */
foreach ($form->getDisplayGroups() as $group) {
$groupName = $group->getName();
foreach ($group->getElements() as $name => $e) {

View File

@ -1,151 +0,0 @@
<?php
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Objects\IcingaHost;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
class IcingaNotificationAssignmentForm extends DirectorObjectForm
{
/**
*
* Please note that $object would conflict with logic in parent class
*/
private $icingaObject;
protected $db;
public function setDb($db)
{
$this->db = $db;
return $this;
}
public function setIcingaObject($object)
{
$this->icingaObject = $object;
return $this;
}
public function setup()
{
$this->addHidden('service_id', $this->icingaObject->id);
if ($this->icingaObject->isTemplate()) {
$this->addHtmlHint(
'Assign all services importing this service template to one or'
. ' more hosts'
);
} else {
$this->addHtmlHint(
'Assign this service to one or more hosts'
);
}
$this->addElement('select', 'object_type', array(
'label' => 'Assign',
'required' => true,
'ignore' => true,
'multiOptions' => $this->optionalEnum(
array(
'host_group' => $this->translate('to a host group'),
'host_property' => $this->translate('by host property'),
'host_group_property' => $this->translate('by host group property'),
)
),
'class' => 'autosubmit'
));
if ($this->hasObject()) {// immer da??
$this->setElementValue('object_type', 'host_property');
}
switch ($this->getSentValue('object_type', $this->getValue('object_type'))) {
case 'host_group':
$this->addHostGroupElements();
break;
case 'host_property':
$this->addHostPropertyElements();
break;
case 'host_property':
$this->addHostFilterElements();
break;
}
if ($this->object) {
$this->setElementValue('host_property', 'host.address');
}
$this->setSubmitLabel(
$this->translate('Assign')
);
$this->setButtons();
}
protected function addHostGroupElements()
{
$this->addElement('select', 'host_id', array(
'label' => 'Hostgroup',
'ignore' => true,
'required' => true,
'multiOptions' => $this->optionalEnum($this->db->enumHostgroups())
));
}
protected function addHostPropertyElements()
{
$this->addElement('select', 'host_property', array(
'label' => 'Host property',
'ignore' => true,
'required' => true,
'multiOptions' => $this->optionalEnum(IcingaHost::enumProperties($this->db))
));
$this->addElement('text', 'filter_expression', array(
'label' => 'Filter expression',
'ignore' => true,
'required' => true,
));
}
protected function addHostFilterElements()
{
$this->addElement('text', 'host_filter', array(
'label' => 'Host filter string',
'required' => true,
));
}
public function onSuccess()
{
switch ($this->getValue('object_type')) {
case 'host_group':
$this->db->insert('icinga_service_assignment', array(
'service_id' => $this->getValue('service_id'),
// TODO: in?
'filter_string' => 'groups=' . $this->getValue('host_group'),
));
break;
case 'host_property':
$filter = sprintf(
'host.%s=%s',
$this->getValue('host_property'),
c::renderString($this->getValue('filter_expression'))
);
$this->setElementValue('filter_string', $filter);
$this->object()->filter_string = $filter;
break;
case 'host_filter':
$this->db->insert('icinga_service_assignment', array(
'service_id' => $this->getValue('service_id'),
'filter_string' => $this->getValue('filter_string'),
));
break;
}
return parent::onSuccess();
}
}

View File

@ -37,6 +37,9 @@ class IcingaNotificationForm extends DirectorObjectForm
->setButtons();
}
/**
* @return self
*/
protected function addAssignmentElements()
{
if (!$this->object || !$this->object->isApplyRule()) {
@ -80,6 +83,9 @@ class IcingaNotificationForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addUsersElement()
{
$users = $this->enumUsers();
@ -102,6 +108,9 @@ class IcingaNotificationForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addUsergroupsElement()
{
$groups = $this->enumUsergroups();
@ -124,6 +133,9 @@ class IcingaNotificationForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addIntervalElement()
{
$this->addElement(
@ -142,6 +154,9 @@ class IcingaNotificationForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addTimesElements()
{
$this->addElement(
@ -169,6 +184,9 @@ class IcingaNotificationForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addPeriodElement()
{
$periods = $this->db->enumTimeperiods();
@ -192,6 +210,9 @@ class IcingaNotificationForm extends DirectorObjectForm
return $this;
}
/**
* @return self
*/
protected function addCommandElements()
{
if (! $this->isTemplate()) {

View File

@ -8,10 +8,7 @@ use Icinga\Module\Director\Web\Form\DirectorObjectForm;
class IcingaObjectFieldForm extends DirectorObjectForm
{
/**
*
* Please note that $object would conflict with logic in parent class
*/
/** @var IcingaObject Please note that $object would conflict with logic in parent class */
protected $icingaObject;
public function setIcingaObject($object)
@ -24,7 +21,7 @@ class IcingaObjectFieldForm extends DirectorObjectForm
public function setup()
{
$type = $this->icingaObject->getShortTableName();
$this->addHidden($type . '_id', $this->icingaObject->id);
$this->addHidden($type . '_id', $this->icingaObject->get('id'));
$this->addHtmlHint(
'Custom data fields allow you to easily fill custom variables with'
@ -160,8 +157,8 @@ class IcingaObjectFieldForm extends DirectorObjectForm
'datatype' => 'Icinga\Module\Director\DataType\DataTypeString'
));
$field->store($this->getDb());
$this->setElementValue('datafield_id', $field->id);
$this->object()->datafield_id = $field->id;
$this->setElementValue('datafield_id', $field->get('id'));
$this->object()->set('datafield_id', $field->get('id'));
}
return parent::onSuccess();

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Objects\IcingaTimePeriod;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
@ -14,7 +15,7 @@ class IcingaTimePeriodRangeForm extends DirectorObjectForm
public function setup()
{
$this->addHidden('timeperiod_id', $this->period->id);
$this->addHidden('timeperiod_id', $this->period->get('id'));
$this->addElement('text', 'range_key', array(
'label' => $this->translate('Day(s)'),
'description' => $this->translate(
@ -58,7 +59,7 @@ class IcingaTimePeriodRangeForm extends DirectorObjectForm
$object->hasBeenLoadedFromDb()
? $this->translate('The %s has successfully been stored')
: $this->translate('A new %s has successfully been created'),
$this->translate($this->getObjectName())
$this->translate($this->getObjectShortClassName())
);
$this->period->store($this->db);
@ -71,7 +72,7 @@ class IcingaTimePeriodRangeForm extends DirectorObjectForm
}
if ($object instanceof IcingaObject) {
$this->setSuccessUrl(
'director/' . strtolower($this->getObjectName()),
'director/' . strtolower($this->getObjectShortClassName()),
$object->getUrlParams()
);
}

View File

@ -10,7 +10,8 @@ class IcingaUserForm extends DirectorObjectForm
{
$this->addObjectTypeElement();
if (! $this->hasObjectType()) {
return $this->groupMainProperties();
$this->groupMainProperties();
return;
}
if ($this->isTemplate()) {

View File

@ -3,13 +3,12 @@
// TODO: Check whether this can be removed
namespace Icinga\Module\Director\Forms;
use Exception;
use Icinga\Module\Director\Import\Import;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Web\Form\QuickForm;
class ImportCheckForm extends QuickForm
{
/** @var ImportSource */
protected $source;
public function setImportSource(ImportSource $source)
@ -44,7 +43,7 @@ class ImportCheckForm extends QuickForm
);
}
if ($source->import_state === 'failing') {
if ($source->get('import_state') === 'failing') {
$this->addError($this->translate('Checking this Import Source failed'));
} else {
parent::onSuccess();

View File

@ -2,8 +2,11 @@
namespace Icinga\Module\Director\Forms;
use Exception;
use Icinga\Application\Hook;
use Icinga\Exception\ConfigurationError;
use Icinga\Module\Director\Hook\ImportSourceHook;
use Icinga\Module\Director\Hook\PropertyModifierHook;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
@ -61,7 +64,7 @@ class ImportRowModifierForm extends DirectorObjectForm
if ($class && array_key_exists($class, $mods)) {
$this->addSettings($class);
}
} elseif ($class = $this->object()->provider_class) {
} elseif ($class = $this->object()->get('provider_class')) {
$this->addSettings($class);
}
@ -99,6 +102,7 @@ class ImportRowModifierForm extends DirectorObjectForm
protected function enumModifiers()
{
/** @var PropertyModifierHook[] $hooks */
$hooks = Hook::all('Director\\PropertyModifier');
$enum = array();
foreach ($hooks as $hook) {

View File

@ -3,13 +3,12 @@
// TODO: Check whether this can be removed
namespace Icinga\Module\Director\Forms;
use Exception;
use Icinga\Module\Director\Import\Import;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Web\Form\QuickForm;
class ImportRunForm extends QuickForm
{
/** @var ImportSource */
protected $source;
public function setImportSource(ImportSource $source)

View File

@ -2,6 +2,8 @@
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\Hook\ImportSourceHook;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Web\Hook;
@ -40,6 +42,7 @@ class ImportSourceForm extends DirectorObjectForm
if ($this->hasObject()) {
$value = $this->getSentValue($name);
if ($value === null) {
/** @var ImportSource $object */
$object = $this->getObject();
return $object->getSetting($name, $default);
@ -51,7 +54,7 @@ class ImportSourceForm extends DirectorObjectForm
}
}
protected function addSettings($class = null)
protected function addSettings()
{
if (! ($class = $this->getProviderClass())) {
return;
@ -100,8 +103,8 @@ class ImportSourceForm extends DirectorObjectForm
if ($this->hasBeenSent()) {
$class = $this->getRequest()->getPost('provider_class');
} else {
if (! ($class = $this->object()->provider_class)) {
return;
if (! ($class = $this->object()->get('provider_class'))) {
return null;
}
}
@ -113,7 +116,7 @@ class ImportSourceForm extends DirectorObjectForm
if (! $this->getValue('key_column')) {
if ($default = $this->getDefaultKeyColumnName()) {
$this->setElementValue('key_column', $default);
$this->object()->key_column = $default;
$this->object()->set('key_column', $default);
}
}
@ -122,6 +125,7 @@ class ImportSourceForm extends DirectorObjectForm
protected function enumSourceTypes()
{
/** @var ImportSourceHook[] $hooks */
$hooks = Hook::all('Director\\ImportSource');
$enum = array();

View File

@ -143,11 +143,11 @@ class KickstartForm extends QuickForm
if ($ep = $this->endpoint) {
$user = $ep->getApiUser();
$this->setDefaults(array(
'endpoint' => $ep->object_name,
'host' => $ep->host,
'port' => $ep->port,
'username' => $user->object_name,
'password' => $user->password,
'endpoint' => $ep->get('object_name'),
'host' => $ep->get('host'),
'port' => $ep->get('port'),
'username' => $user->get('object_name'),
'password' => $user->get('password'),
));
if (! empty($user->password)) {
@ -321,7 +321,7 @@ class KickstartForm extends QuickForm
try {
if ($this->getSubmitLabel() === $this->storeConfigLabel) {
if ($this->storeResourceConfig()) {
return parent::onSuccess();
parent::onSuccess();
} else {
return;
}
@ -330,7 +330,7 @@ class KickstartForm extends QuickForm
if ($this->getSubmitLabel() === $this->createDbLabel
|| $this->getSubmitLabel() === $this->migrateDbLabel) {
$this->migrations()->applyPendingMigrations();
return parent::onSuccess();
parent::onSuccess();
}
$values = $this->getValues();
@ -354,6 +354,8 @@ class KickstartForm extends QuickForm
$resources = $this->enumResources();
if (in_array($resource, $resources)) {
return $resource;
} else {
return null;
}
} else {
return $this->config()->get('db', 'resource');
@ -396,7 +398,7 @@ class KickstartForm extends QuickForm
$allowed = array('mysql', 'pgsql');
foreach (ResourceFactory::getResourceConfigs() as $name => $resource) {
if ($resource->type === 'db' && in_array($resource->db, $allowed)) {
if ($resource->get('type') === 'db' && in_array($resource->get('db'), $allowed)) {
$resources[$name] = $name;
}
}

View File

@ -9,8 +9,10 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class RestoreObjectForm extends QuickForm
{
/** @var Db */
protected $db;
/** @var IcingaObject */
protected $object;
public function setup()
@ -28,7 +30,7 @@ class RestoreObjectForm extends QuickForm
public function onSuccess()
{
$object = $this->object;
$name = $object->object_name;
$name = $object->getObjectName();
$db = $this->db;
$msg = $this->translate('Object has been restored');

View File

@ -8,6 +8,7 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class SettingsForm extends QuickForm
{
/** @var Settings */
protected $settings;
public function setup()
@ -101,11 +102,7 @@ class SettingsForm extends QuickForm
public function onSuccess()
{
$settings = $this->settings;
try {
$cnt = 0;
foreach ($this->getValues() as $key => $value) {
if ($value === '') {
$value = null;

View File

@ -8,6 +8,7 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class SyncCheckForm extends QuickForm
{
/** @var SyncRule */
protected $rule;
public function setSyncRule(SyncRule $rule)
@ -31,7 +32,6 @@ class SyncCheckForm extends QuickForm
$this->notifySuccess(
$this->translate(('This Sync Rule would apply new changes'))
);
$html = '';
$sum = array('create' => 0, 'modify' => 0, 'delete' => 0);
// TODO: Preview them? Like "hosta, hostb and 4 more would be...
@ -54,7 +54,7 @@ class SyncCheckForm extends QuickForm
$html = '<pre>' . print_r($sum, 1) . '</pre>';
$this->addHtml($html);
} elseif ($this->rule->sync_state === 'in-sync') {
} elseif ($this->rule->get('sync_state') === 'in-sync') {
$this->setSuccessMessage(
$this->translate('Nothing would change, this rule is still in sync')
);

View File

@ -3,7 +3,6 @@
namespace Icinga\Module\Director\Forms;
use Exception;
use Icinga\Exception\InvalidPropertyException;
use Icinga\Module\Director\Hook\ImportSourceHook;
use Icinga\Module\Director\Objects\SyncRule;
use Icinga\Module\Director\Objects\IcingaObject;
@ -17,6 +16,7 @@ class SyncPropertyForm extends DirectorObjectForm
*/
private $rule;
/** @var ImportSource */
private $importSource;
private $dummyObject;
@ -25,7 +25,7 @@ class SyncPropertyForm extends DirectorObjectForm
public function setup()
{
$this->addHidden('rule_id', $this->rule_id);
$this->addHidden('rule_id', $this->rule->get('id'));
$this->addElement('select', 'source_id', array(
'label' => $this->translate('Source Name'),
@ -159,7 +159,7 @@ class SyncPropertyForm extends DirectorObjectForm
}
if ($destination === 'import') {
$funcTemplates = 'enum' . ucfirst($this->rule->object_type) . 'Templates';
$funcTemplates = 'enum' . ucfirst($this->rule->get('object_type')) . 'Templates';
$templates = $this->db->$funcTemplates();
if (! empty($templates)) {
$templates = array_combine($templates, $templates);
@ -259,7 +259,7 @@ class SyncPropertyForm extends DirectorObjectForm
$dummy = $this->dummyObject();
if ($dummy instanceof IcingaObject) {
if ($dummy->supportsCustomvars()) {
if ($dummy->supportsCustomVars()) {
$special['vars.*'] = $this->translate('Custom variable (vars.)');
$special['vars'] = $this->translate('All custom variables (vars)');
}
@ -310,11 +310,11 @@ class SyncPropertyForm extends DirectorObjectForm
{
if ($this->importSource === null) {
if ($this->hasObject()) {
$src = ImportSource::load($this->object->source_id, $this->db);
$src = ImportSource::load($this->object->get('source_id'), $this->db);
} else {
$src = ImportSource::load($this->getSentValue('source_id'), $this->db);
}
$this->importSource = ImportSourceHook::loadByName($src->source_name, $this->db);
$this->importSource = ImportSourceHook::loadByName($src->get('source_name'), $this->db);
}
return $this->importSource;
@ -323,10 +323,10 @@ class SyncPropertyForm extends DirectorObjectForm
public function onSuccess()
{
$object = $this->getObject();
$object->rule_id = $this->rule->id; // ?!
$object->set('rule_id', $this->rule->get('id')); // ?!
if ($this->getValue('use_filter') === 'n') {
$object->filter_expression = null;
$object->set('filter_expression', null);
}
$sourceColumn = $this->getValue('source_column');
@ -357,7 +357,7 @@ class SyncPropertyForm extends DirectorObjectForm
{
if ($this->dummyObject === null) {
$this->dummyObject = IcingaObject::createByType(
$this->rule->object_type,
$this->rule->get('object_type'),
array(),
$this->db
);

View File

@ -8,6 +8,7 @@ use Icinga\Module\Director\Web\Form\QuickForm;
class SyncRunForm extends QuickForm
{
/** @var SyncRule */
protected $rule;
public function setSyncRule(SyncRule $rule)
@ -31,11 +32,10 @@ class SyncRunForm extends QuickForm
$changed = $rule->applyChanges();
if ($changed) {
$runId = $rule->getCurrentSyncRunId();
$this->setSuccessMessage(
$this->translate(('Source has successfully been synchronized'))
);
} elseif ($rule->sync_state === 'in-sync') {
} elseif ($rule->get('sync_state') === 'in-sync') {
$this->setSuccessMessage(
$this->translate('Nothing changed, rule is in sync')
);

View File

@ -3,14 +3,17 @@
namespace Icinga\Module\Director\Cli;
use Icinga\Cli\Command as CliCommand;
use Icinga\Module\Director\Core\CoreApi;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\IcingaEndpoint;
use Icinga\Application\Config;
class Command extends CliCommand
{
/** @var Db */
protected $db;
/** @var CoreApi */
private $api;
protected function renderJson($object, $pretty = true)
@ -53,8 +56,6 @@ class Command extends CliCommand
default:
return 'An error occured when parsing a JSON string';
}
return $this;
}
protected function api($endpointName = null)
@ -72,6 +73,9 @@ class Command extends CliCommand
return $this->api;
}
/**
* @return Db
*/
protected function db()
{
if ($this->db === null) {

View File

@ -3,7 +3,6 @@
namespace Icinga\Module\Director\Cli;
use Icinga\Exception\MissingParameterException;
use Icinga\Module\Director\Cli\Command;
use Icinga\Module\Director\Objects\IcingaObject;
class ObjectCommand extends Command
@ -85,11 +84,9 @@ class ObjectCommand extends Command
*/
public function createAction()
{
$db = $this->db();
$type = $this->getType();
$name = $this->params->shift();
$db = $this->db();
$props = $this->remainingParams();
if (! array_key_exists('object_type', $props)) {
$props['object_type'] = 'object';
@ -176,7 +173,6 @@ class ObjectCommand extends Command
*/
public function setAction()
{
$db = $this->db();
$name = $this->getName();
if ($this->params->shift('auto-create') && ! $this->exists($name)) {
@ -371,6 +367,9 @@ class ObjectCommand extends Command
);
}
/**
* @return IcingaObject
*/
protected function getObject()
{
if ($this->object === null) {

View File

@ -9,6 +9,7 @@ use Icinga\Module\Director\IcingaConfig\IcingaConfig;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Objects\IcingaCommand;
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
use Icinga\Module\Director\Objects\IcingaZone;
class CoreApi
{
@ -104,8 +105,8 @@ class CoreApi
public function getHostOutput($host)
{
try {
$object = $this->getObject($host);
} catch (\Exception $e) {
$object = $this->getObject($host, 'hosts');
} catch (Exception $e) {
return 'Unable to fetch the requested object';
}
if (isset($object->attrs->last_check_result)) {
@ -120,7 +121,6 @@ class CoreApi
$this->checkHostNow($host);
$now = time();
$waiting = true;
while (true) {
try {
$object = $this->getObject($host, 'hosts');
@ -193,7 +193,7 @@ class CoreApi
. "\n if (existing) { return false }"
. "\n%s\n}\n__run_with_activation_context(f)\n",
$key,
$object->object_name,
$object->get('object_name'),
(string) $object
);
@ -280,7 +280,7 @@ constants
public function getActiveChecksum(Db $conn)
{
$db = $conn->getConnection();
$db = $conn->getDbAdapter();
$stage = $this->getActiveStageName();
if (! $stage) {
return null;
@ -323,6 +323,9 @@ constants
return $objects;
}
/**
* @return IcingaZone[]
*/
public function getZoneObjects()
{
return $this->getDirectorObjects('Zone', 'Zone', 'zones', array(
@ -486,12 +489,11 @@ constants
return $found;
}
public function collectLogFiles($db)
public function collectLogFiles(Db $db)
{
$existing = $this->listModuleStages('director');
foreach ($db->getUncollectedDeployments() as $deployment) {
$stage = $deployment->stage_name;
$stage = $deployment->get('stage_name');
if (! in_array($stage, $existing)) {
continue;
}
@ -499,8 +501,8 @@ constants
try {
$availableFiles = $this->listStageFiles($stage);
} catch (Exception $e) {
// This is not correct. We might miss logs as af an ongoing reload
$deployment->stage_collected = 'y';
// TODO: This is not correct. We might miss logs as af an ongoing reload
$deployment->set('stage_collected', 'y');
$deployment->store();
continue;
}
@ -509,21 +511,21 @@ constants
&& in_array('status', $availableFiles)
) {
if ($this->getStagedFile($stage, 'status') === '0') {
$deployment->startup_succeeded = 'y';
$deployment->set('startup_succeeded', 'y');
} else {
$deployment->startup_succeeded = 'n';
$deployment->set('startup_succeeded', 'n');
}
$deployment->startup_log = $this->shortenStartupLog(
$deployment->set('startup_log', $this->shortenStartupLog(
$this->getStagedFile($stage, 'startup.log')
);
));
}
$collected = true;
$deployment->set('stage_collected', 'y');
$deployment->store();
}
}
public function wipeInactiveStages($db)
public function wipeInactiveStages(Db $db)
{
$uncollected = $db->getUncollectedDeployments();
$moduleName = 'director';
@ -614,7 +616,6 @@ constants
public function dumpConfig(IcingaConfig $config, $db, $moduleName = 'director')
{
$start = microtime(true);
$data = $config->getFileContents();
$deployment = DirectorDeploymentLog::create(array(
// 'config_id' => $config->id,
// 'peer_identity' => $endpoint->object_name,
@ -638,21 +639,21 @@ constants
$duration = (int) ((microtime(true) - $start) * 1000);
// $deployment->duration_ms = $duration;
$deployment->duration_dump = $duration;
$deployment->set('duration_dump', $duration);
if ($response->succeeded()) {
if ($stage = $response->getResult('stage', array('package' => $moduleName))) { // Status?
$deployment->stage_name = key($stage);
$deployment->dump_succeeded = 'y';
$deployment->set('stage_name', key($stage));
$deployment->set('dump_succeeded', 'y');
} else {
$deployment->dump_succeeded = 'n';
$deployment->set('dump_succeeded', 'n');
}
} else {
$deployment->dump_succeeded = 'n';
$deployment->set('dump_succeeded', 'n');
}
$deployment->store($db);
return $deployment->dump_succeeded === 'y';
return $deployment->set('dump_succeeded', 'y');
}
protected function shortenStartupLog($log)

View File

@ -219,6 +219,11 @@ class RestApiClient
return $this->request('delete', $url, $body);
}
/**
* @throws Exception
*
* @return resource
*/
protected function curl()
{
if ($this->curl === null) {
@ -227,16 +232,8 @@ class RestApiClient
throw new Exception('CURL INIT ERROR: ' . curl_error($this->curl));
}
}
return $this->curl;
}
protected function readPart($curl, $data)
{
$length = strlen($data);
$this->readBuffer .= $data;
// echo "Got $length bytes\n";
$this->processEvents();
return $length;
return $this->curl;
}
protected function processEvents()

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Director\CustomVariable;
use Icinga\Exception\ProgrammingError;
use Icinga\Module\Director\Db\Cache\PrefetchCache;
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
use Exception;
abstract class CustomVariable implements IcingaConfigRenderer
{
@ -39,7 +40,6 @@ abstract class CustomVariable implements IcingaConfigRenderer
{
if ($this->type === null) {
$parts = explode('\\', get_class($this));
$class = end($parts);
// strlen('CustomVariable') === 9
$this->type = substr(end($parts), 9);
}
@ -78,6 +78,8 @@ abstract class CustomVariable implements IcingaConfigRenderer
abstract public function setValue($value);
abstract public function getValue();
public function isNew()
{
return ! $this->loadedFromDb;

View File

@ -6,6 +6,9 @@ use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
class CustomVariableArray extends CustomVariable
{
/** @var CustomVariable[] */
protected $value;
public function equals(CustomVariable $var)
{
if (! $var instanceof CustomVariableArray) {

View File

@ -7,6 +7,9 @@ use Countable;
class CustomVariableDictionary extends CustomVariable implements Countable
{
/** @var CustomVariable[] */
protected $value;
public function equals(CustomVariable $var)
{
if (! $var instanceof CustomVariableDictionary) {

View File

@ -2,7 +2,6 @@
namespace Icinga\Module\Director\CustomVariable;
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
use Icinga\Exception\ProgrammingError;
class CustomVariableNull extends CustomVariable

View File

@ -6,11 +6,13 @@ use Icinga\Module\Director\Db;
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
use Icinga\Module\Director\Objects\IcingaObject;
use Iterator;
use Countable;
use Exception;
use Iterator;
class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
{
/** @var CustomVariable[] */
protected $storedVars = array();
protected $vars = array();
@ -37,7 +39,7 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
$where = $db->quoteInto('varname = ?', $varname);
foreach (static::$allTables as $table) {
$parts[] = sprintf(
'SELECT COUNT(*) as cnt FROM icinga_host_var WHERE %s',
'SELECT COUNT(*) as cnt FROM ' . $table . ' WHERE %s',
$where
);
}
@ -102,10 +104,10 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
/**
* Generic setter
*
* @param string $property
* @param string $key
* @param mixed $value
*
* @return array
* @return self
*/
public function set($key, $value)
{
@ -163,7 +165,7 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
'v.varvalue',
'v.format',
)
)->where(sprintf('v.%s = ?', $object->getVarsIdColumn()), $object->id);
)->where(sprintf('v.%s = ?', $object->getVarsIdColumn()), $object->get('id'));
$vars = new CustomVariables;
foreach ($db->fetchAll($query) as $row) {
@ -191,7 +193,7 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
$db = $object->getDb();
$table = $object->getVarsTableName();
$foreignColumn = $object->getVarsIdColumn();
$foreignId = $object->id;
$foreignId = $object->get('id');
foreach ($this->vars as $var) {
@ -282,6 +284,13 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
return $out;
}
/**
* @param string $key
* @param CustomVariable $var
* @param bool $renderExpressions
*
* @return string
*/
protected function renderSingleVar($key, $var, $renderExpressions = false)
{
return c::renderKeyValue(
@ -320,6 +329,8 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
/**
* Magic isset check
*
* @param string $key
*
* @return boolean
*/
public function __isset($key)
@ -330,6 +341,8 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
/**
* Magic unsetter
*
* @param string $key
*
* @return void
*/
public function __unset($key)

View File

@ -13,18 +13,28 @@ abstract class Dashboard implements Countable
{
protected $name;
/** @var Dashlet[] */
protected $dashlets;
protected $dashletNames;
/** @var Db */
protected $db;
/** @var View */
protected $view;
final private function __construct()
{
}
/**
* @param $name
* @param Db $db
* @param View $view
*
* @return self
*/
public static function loadByName($name, Db $db, View $view)
{
$class = __NAMESPACE__ . '\\' . ucfirst($name) . 'Dashboard';

View File

@ -30,6 +30,9 @@ abstract class Dashlet
$this->db = $dashboard->getDb();
}
/**
* @return string[]
*/
public function listRequiredStats()
{
return $this->requiredStats;

View File

@ -2,10 +2,8 @@
namespace Icinga\Module\Director\Dashboard\Dashlet;
use DirectoryIterator;
use Exception;
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
use Icinga\Exception\ProgrammingError;
class DeploymentDashlet extends Dashlet
{

View File

@ -40,6 +40,8 @@ class EndpointObjectDashlet extends Dashlet
if (! $this->hasDeploymentEndpoint()) {
return 'state-critical';
}
return null;
}
public function getSummary()

View File

@ -2,9 +2,6 @@
namespace Icinga\Module\Director\Dashboard\Dashlet;
use DirectoryIterator;
use Icinga\Exception\ProgrammingError;
class HostObjectDashlet extends Dashlet
{
protected $icon = 'host';

View File

@ -33,6 +33,7 @@ class JobDashlet extends Dashlet
protected function fetchStateClass()
{
/** @var DirectorJob[] $jobs */
$jobs = DirectorJob::loadAll($this->db);
if (count($jobs) > 0) {
$state = 'state-ok';

View File

@ -2,9 +2,6 @@
namespace Icinga\Module\Director\Dashboard\Dashlet;
use DirectoryIterator;
use Icinga\Exception\ProgrammingError;
class NotificationObjectDashlet extends Dashlet
{
protected $icon = 'megaphone';

View File

@ -2,9 +2,6 @@
namespace Icinga\Module\Director\Dashboard\Dashlet;
use DirectoryIterator;
use Icinga\Exception\ProgrammingError;
class ServiceObjectDashlet extends Dashlet
{
protected $icon = 'services';

View File

@ -2,8 +2,6 @@
namespace Icinga\Module\Director\Dashboard;
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
class DataDashboard extends Dashboard
{
protected $name;

View File

@ -2,8 +2,6 @@
namespace Icinga\Module\Director\Dashboard;
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
class DeploymentDashboard extends Dashboard
{
protected $name;

View File

@ -2,10 +2,6 @@
namespace Icinga\Module\Director\Dashboard;
use Countable;
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
class ObjectsDashboard extends Dashboard
{
protected $name;

View File

@ -0,0 +1,24 @@
<?php
namespace Icinga\Module\Director\Data\Db;
use Icinga\Data\Db\DbConnection as IcingaDbConnection;
class DbConnection extends IcingaDbConnection
{
public function isPgsql()
{
return $this->getDbType() === 'pgsql';
}
public function hasPgExtension($name)
{
$db = $this->db();
$query = $db->select()->from(
array('e' => 'pg_extension'),
array('cnt' => 'COUNT(*)')
)->where('extname = ?', $name);
return (int) $db->fetchOne($query) === 1;
}
}

View File

@ -8,35 +8,34 @@
*/
namespace Icinga\Module\Director\Data\Db;
use Icinga\Data\Db\DbConnection;
use Icinga\Module\Director\Util;
use Icinga\Exception\IcingaException as IE;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Director\Util;
use Exception;
use Zend_Db_Adapter_Abstract;
/**
* Base class for ...
*/
abstract class DbObject
{
/**
* DbConnection
*/
/** @var DbConnection $connection */
protected $connection;
/**
* Zend_Db_Adapter_Abstract: DB Handle
*/
/** @var string Table name. MUST be set when extending this class */
protected $table;
/** @var Zend_Db_Adapter_Abstract */
protected $db;
/**
* Table name. MUST be set when extending this class
*/
protected $table;
/** @var Zend_Db_Adapter_Abstract */
protected $r;
/**
* Default columns. MUST be set when extending this class. Each table
* column MUST be defined with a default value. Default value may be null.
*
* @var array
*/
protected $defaultProperties;
@ -234,6 +233,8 @@ abstract class DbObject
*
* @param string $property Property
*
* @throws IE
*
* @return mixed
*/
public function get($property)
@ -271,10 +272,12 @@ abstract class DbObject
/**
* Generic setter
*
* @param string $property
* @param string $key
* @param mixed $value
*
* @return array
* @throws IE
*
* @return self
*/
public function set($key, $value)
{
@ -333,6 +336,8 @@ abstract class DbObject
/**
* Magic getter
*
* @param mixed $key
*
* @return mixed
*/
public function __get($key)
@ -356,6 +361,7 @@ abstract class DbObject
/**
* Magic isset check
*
* @param string $key
* @return boolean
*/
public function __isset($key)
@ -366,6 +372,8 @@ abstract class DbObject
/**
* Magic unsetter
*
* @param string $key
* @throws IE
* @return void
*/
public function __unset($key)
@ -377,10 +385,10 @@ abstract class DbObject
}
/**
* Führt die Operation set() für jedes Element (key/value Paare) der über-
* gebenen Arrays aus
* Runs set() for every key/value pair of the given Array
*
* @param array $data Array mit den zu setzenden Daten
* @param array $props Array of properties
* @throws IE
* @return self
*/
public function setProperties($props)
@ -567,6 +575,7 @@ abstract class DbObject
* Lädt einen Datensatz aus der Datenbank und setzt die entsprechenden
* Eigenschaften dieses Objekts
*
* @throws NotFoundError
* @return self
*/
protected function loadFromDb()
@ -679,7 +688,9 @@ abstract class DbObject
/**
* Store object to database
*
* @return boolean Whether storing succeeded
* @param DbConnection $db
* @return bool Whether storing succeeded
* @throws IE
*/
public function store(DbConnection $db = null)
{
@ -722,7 +733,6 @@ abstract class DbObject
}
if ($this->insertIntoDb()) {
$id = $this->getId();
if ($this->autoincKeyName) {
if ($this->connection->isPgsql()) {
$this->properties[$this->autoincKeyName] = $this->db->lastInsertId(
@ -732,9 +742,6 @@ abstract class DbObject
} else {
$this->properties[$this->autoincKeyName] = $this->db->lastInsertId();
}
if (! $id) {
$id = '[' . $this->properties[$this->autoincKeyName] . ']';
}
}
// $this->log(sprintf('New %s "%s" has been stored', $table, $id));
$this->onInsert();
@ -783,6 +790,11 @@ abstract class DbObject
);
}
/**
* @param string $key
* @return self
* @throws IE
*/
protected function setKey($key)
{
$keyname = $this->getKeyName();
@ -922,10 +934,15 @@ abstract class DbObject
{
}
/**
* @param array $properties
* @param DbConnection|null $connection
*
* @return static
*/
public static function create($properties = array(), DbConnection $connection = null)
{
$class = get_called_class();
$obj = new $class();
$obj = new static();
if ($connection !== null) {
$obj->setConnection($connection);
}
@ -989,7 +1006,7 @@ abstract class DbObject
self::$prefetchStats[$class]->miss++;
return false;
}
return array_key_exists($key, self::$prefetched[$class]);
} else {
self::$prefetchStats[$class]->miss++;
return false;
@ -1007,8 +1024,8 @@ abstract class DbObject
return $prefetched;
}
$class = get_called_class();
$obj = new $class();
/** @var DbObject $obj */
$obj = new static;
$obj->setConnection($connection)
->set($obj->autoincKeyName, $id)
->loadFromDb();
@ -1021,20 +1038,26 @@ abstract class DbObject
return $prefetched;
}
$class = get_called_class();
$obj = new $class();
/** @var DbObject $obj */
$obj = new static;
$obj->setConnection($connection)->setKey($id)->loadFromDb();
return $obj;
}
/**
* @param DbConnection $connection
* @param \Zend_Db_Select $query
* @param string|null $keyColumn
*
* @return self[]
*/
public static function loadAll(DbConnection $connection, $query = null, $keyColumn = null)
{
$objects = array();
$class = get_called_class();
$db = $connection->getDbAdapter();
if ($query === null) {
$dummy = new $class();
$dummy = new static;
$select = $db->select()->from($dummy->table);
} else {
$select = $query;
@ -1043,7 +1066,8 @@ abstract class DbObject
$rows = $db->fetchAll($select);
foreach ($rows as $row) {
$obj = new $class();
/** @var DbObject $obj */
$obj = new static;
$obj->setConnection($connection)->setDbProperties($row);
if ($keyColumn === null) {
$objects[] = $obj;
@ -1057,10 +1081,9 @@ abstract class DbObject
public static function prefetchAll(DbConnection $connection, $force = false)
{
$class = get_called_class();
$dummy = $class::create();
$autoInc = $dummy->getAutoIncKeyName();
$dummy = static::create();
$class = get_class($dummy);
$autoInc = $dummy->getAutoincKeyName();
$keyName = $dummy->getKeyName();
if ($force || ! array_key_exists($class, self::$prefetched)) {
@ -1079,7 +1102,7 @@ abstract class DbObject
{
$class = get_called_class();
if (! array_key_exists($class, self::$prefetched)) {
return false;
return;
}
unset(self::$prefetched[$class]);
@ -1094,6 +1117,11 @@ abstract class DbObject
self::$prefetchStats = array();
}
/**
* @param $id
* @param DbConnection $connection
* @return bool
*/
public static function exists($id, DbConnection $connection)
{
if (static::getPrefetched($id)) {
@ -1102,8 +1130,8 @@ abstract class DbObject
return false;
}
$class = get_called_class();
$obj = new $class();
/** @var DbObject $obj */
$obj = new static;
$obj->setConnection($connection)->setKey($id);
return $obj->existsInDb();
}

View File

@ -54,7 +54,7 @@ abstract class DbObjectWithSettings extends DbObject
public function __unset($key)
{
if ($this->hasProperty($key)) {
return parent::__set($key, $value);
return parent::__unset($key);
}
if (array_key_exists($key, $this->settings)) {
@ -73,6 +73,7 @@ abstract class DbObjectWithSettings extends DbObject
$add = array();
$mod = array();
$del = array();
$id = $this->get('id');
foreach ($this->settings as $key => $val) {
if (array_key_exists($key, $old)) {
@ -88,7 +89,7 @@ abstract class DbObjectWithSettings extends DbObject
$del[] = $key;
}
$where = sprintf($this->settingsRemoteId . ' = %d AND setting_name = ?', $this->id);
$where = sprintf($this->settingsRemoteId . ' = %d AND setting_name = ?', $id);
$db = $this->getDb();
foreach ($mod as $key => $val) {
$db->update(
@ -102,7 +103,7 @@ abstract class DbObjectWithSettings extends DbObject
$db->insert(
$this->settingsTable,
array(
$this->settingsRemoteId => $this->id,
$this->settingsRemoteId => $id,
'setting_name' => $key,
'setting_value' => $val
)
@ -110,7 +111,7 @@ abstract class DbObjectWithSettings extends DbObject
}
if (! empty($del)) {
$where = sprintf($this->settingsRemoteId . ' = %d AND setting_name IN (?)', $this->id);
$where = sprintf($this->settingsRemoteId . ' = %d AND setting_name IN (?)', $id);
$db->delete($this->settingsTable, $db->quoteInto($where, $del));
}
}
@ -121,7 +122,7 @@ abstract class DbObjectWithSettings extends DbObject
return $db->fetchPairs(
$db->select()
->from($this->settingsTable, array('setting_name', 'setting_value'))
->where($this->settingsRemoteId . ' = ?', $this->id)
->where($this->settingsRemoteId . ' = ?', $this->get('id'))
);
}

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Director\DataType;
use Icinga\Module\Director\Hook\DataTypeHook;
use Icinga\Module\Director\Web\Form\Decorator\ViewHelperRaw;
use Icinga\Module\Director\Web\Form\QuickForm;
use Zend_Form_Element as ZfElement;
class DataTypeBoolean extends DataTypeHook
{
@ -15,7 +16,7 @@ class DataTypeBoolean extends DataTypeHook
);
}
protected function applyRawViewHelper($element)
protected function applyRawViewHelper(ZfElement $element)
{
$vhClass = 'Zend_Form_Decorator_ViewHelper';
$decorators = $element->getDecorators();

View File

@ -4,6 +4,7 @@ namespace Icinga\Module\Director\DataType;
use Icinga\Module\Director\Hook\DataTypeHook;
use Icinga\Module\Director\Web\Form\QuickForm;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
class DataTypeDatalist extends DataTypeHook
{
@ -17,8 +18,9 @@ class DataTypeDatalist extends DataTypeHook
return $element;
}
protected function getEntries($form)
protected function getEntries(QuickForm $form)
{
/** @var DirectorObjectForm $form */
$db = $form->getDb()->getDbAdapter();
$select = $db->select()
@ -31,6 +33,7 @@ class DataTypeDatalist extends DataTypeHook
public static function addSettingsFormFields(QuickForm $form)
{
/** @var DirectorObjectForm $form */
$db = $form->getDb();
$form->addElement('select', 'datalist_id', array(

View File

@ -4,12 +4,14 @@ namespace Icinga\Module\Director\DataType;
use Icinga\Module\Director\Hook\DataTypeHook;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Module\Director\Web\Form\QuickForm;
class DataTypeDirectorObject extends DataTypeHook
{
public function getFormElement($name, QuickForm $form)
{
/** @var DirectorObjectForm $form */
$db = $form->getDb()->getDbAdapter();
$dummy = IcingaObject::createByType(

View File

@ -10,6 +10,7 @@ use Icinga\Module\Director\Util;
class DataTypeSqlQuery extends DataTypeHook
{
/** @var \Zend_Db_Adapter_Pdo_Abstract */
protected $db;
protected static $cachedResult;

View File

@ -2,7 +2,8 @@
namespace Icinga\Module\Director;
use Icinga\Data\Db\DbConnection;
use Icinga\Exception\IcingaException;
use Icinga\Module\Director\Data\Db\DbConnection;
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
use Icinga\Module\Director\Objects\IcingaEndpoint;
use Icinga\Module\Director\Objects\IcingaObject;
@ -156,6 +157,9 @@ class Db extends DbConnection
return $name;
}
/**
* @return IcingaEndpoint
*/
public function getDeploymentEndpoint()
{
return IcingaEndpoint::load($this->getDeploymentEndpointName(), $this);
@ -628,22 +632,6 @@ class Db extends DbConnection
return $this->db()->fetchAll($select);
}
public function isPgsql()
{
return $this->getDbType() === 'pgsql';
}
public function hasPgExtension($name)
{
$db = $this->db();
$query = $db->select()->from(
array('e' => 'pg_extension'),
array('cnt' => 'COUNT(*)')
)->where('extname = ?', $name);
return (int) $db->fetchOne($query) === 1;
}
public function dbHexFunc($column)
{
if ($this->isPgsql()) {
@ -688,6 +676,9 @@ class Db extends DbConnection
return $db->fetchPairs($query);
}
/**
* @return DirectorDeploymentLog[]
*/
public function getUncollectedDeployments()
{
$db = $this->db();

View File

@ -39,6 +39,11 @@ class PrefetchCache
$this->db = $db;
}
/**
* @throws ProgrammingError
*
* @return self
*/
public static function instance()
{
if (static::$instance === null) {

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Hook;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Module\Director\Web\Form\QuickForm;
abstract class DataTypeHook
@ -28,6 +29,12 @@ abstract class DataTypeHook
return 'string';
}
/**
* @param $name
* @param QuickForm|DirectorObjectForm $form
*
* @return \Zend_Form_Element
*/
abstract public function getFormElement($name, QuickForm $form);
public static function addSettingsFormFields(QuickForm $form)

View File

@ -28,7 +28,7 @@ abstract class ImportSourceHook
return $class;
}
public static function loadByName($name, $db)
public static function loadByName($name, Db $db)
{
$db = $db->getDbAdapter();
$source = $db->fetchRow(
@ -51,7 +51,7 @@ abstract class ImportSourceHook
$source->provider_class
);
}
/** @var ImportSourceHook $obj */
$obj = new $source->provider_class;
$obj->setSettings($settings);

View File

@ -2,7 +2,6 @@
namespace Icinga\Module\Director\Hook;
use Icinga\Application\Icinga;
use Icinga\Application\Logger;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\DirectorJob;
@ -10,8 +9,10 @@ use Icinga\Module\Director\Web\Form\QuickForm;
abstract class JobHook
{
/** @var Db */
private $db;
/** @var DirectorJob */
private $jobDefinition;
public static function getDescription(QuickForm $form)

View File

@ -25,7 +25,7 @@ class AgentWizard
if ($host->getResolvedProperty('has_agent') !== 'y') {
throw new ProgrammingError(
'The given host "%s" is not an Agent',
$host->object_name
$host->getObjectName()
);
}
@ -36,13 +36,13 @@ class AgentWizard
{
return $this->db()->getDeploymentEndpointName();
// TODO: This is a problem. Should look like this:
return current($this->getParentEndpoints())->object_name;
// TODO: This is a problem with Icinga 2. Should look like this:
// return current($this->getParentEndpoints())->object_name;
}
protected function shouldConnectToMaster()
{
return $this->getResolvedProperty('master_should_connect') !== 'y';
return $this->host->getResolvedProperty('master_should_connect') !== 'y';
}
protected function getParentZone()
@ -82,7 +82,7 @@ class AgentWizard
->from('icinga_endpoint')
->where(
'zone_id = ?',
$this->getParentZone()->id
$this->getParentZone()->get('id')
);
return IcingaEndpoint::loadAll(
@ -109,7 +109,9 @@ class AgentWizard
protected function getTicketSalt()
{
if ($this->salt === null) {
$this->salt = $this->api()->getTicketSalt();
throw new ProgrammingError('Requesting salt, but got none');
// TODO: No API, not yet. Pass in constructor or throw, still tbd
// $this->salt = $this->api()->getTicketSalt();
}
return $this->salt;
@ -117,7 +119,7 @@ class AgentWizard
protected function getCertName()
{
return $this->host->object_name;
return $this->host->getObjectName();
}
protected function loadPowershellModule()
@ -137,7 +139,7 @@ class AgentWizard
array(
'AgentName' => $this->getCertName(),
'Ticket' => $this->getTicket(),
'ParentZone' => $this->getParentZone()->object_name,
'ParentZone' => $this->getParentZone()->getObjectName(),
'ParentEndpoints' => array_keys($this->getParentEndpoints()),
'CAServer' => $this->getCaServer(),
)

View File

@ -4,6 +4,8 @@ namespace Icinga\Module\Director\IcingaConfig;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filter\FilterAnd;
use Icinga\Data\Filter\FilterChain;
use Icinga\Data\Filter\FilterExpression;
use Icinga\Data\Filter\FilterOr;
use Icinga\Data\Filter\FilterNot;
use Icinga\Data\Filter\FilterEqualOrGreaterThan;
@ -48,8 +50,10 @@ class AssignRenderer
protected function renderFilter(Filter $filter)
{
if ($filter->isChain()) {
/** @var FilterChain $filter */
return $this->renderFilterChain($filter);
} else {
/** @var FilterExpression $filter */
return $this->renderFilterExpression($filter);
}
}
@ -71,7 +75,7 @@ class AssignRenderer
}
}
protected function renderFilterExpression($filter)
protected function renderFilterExpression(FilterExpression $filter)
{
$column = $filter->getColumn();
$expression = $filter->getExpression();
@ -151,7 +155,7 @@ class AssignRenderer
}
}
protected function renderFilterChain(Filter $filter)
protected function renderFilterChain(FilterChain $filter)
{
// TODO: brackets if deeper level?
if ($filter instanceof FilterAnd) {
@ -166,6 +170,7 @@ class AssignRenderer
$parts = array();
if (! $filter->isEmpty()) {
/** @var Filter $f */
foreach ($filter->filters() as $f) {
if ($f->isChain()) {
if ($f instanceof FilterNot) {

View File

@ -185,7 +185,7 @@ class ExtensibleSet
'property',
'merge_behaviour'
)
)->where($this->foreignKey() . ' = ?', $this->object->id);
)->where($this->foreignKey() . ' = ?', $this->object->get('id'));
$byBehaviour = array(
'override' => array(),
@ -269,14 +269,14 @@ class ExtensibleSet
$table = $this->tableName();
$props = array(
$this->foreignKey() => $this->object->id
$this->foreignKey() => $this->object->get('id')
);
$db->delete(
$this->tableName(),
$db->quoteInto(
$this->foreignKey() . ' = ?',
$this->object->id
$this->object->get('id')
)
);

View File

@ -7,14 +7,15 @@ use Icinga\Application\Hook;
use Icinga\Application\Icinga;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\IcingaException;
use Icinga\Exception\NotFoundError;
use Icinga\Exception\ProgrammingError;
use Icinga\Module\Director\Db\Cache\PrefetchCache;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Hook\ShipConfigFilesHook;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Util;
use Icinga\Module\Director\Objects\IcingaHost;
use Icinga\Module\Director\Objects\IcingaZone;
use Icinga\Module\Director\Objects\IcingaEndpoint;
use Exception;
class IcingaConfig
{
@ -60,7 +61,7 @@ class IcingaConfig
public function getDuration()
{
return $this->duration;
return $this->generationTime;
}
public function getFileCount()
@ -120,6 +121,9 @@ class IcingaConfig
return Util::binary2hex($this->checksum);
}
/**
* @return IcingaConfigFile[]
*/
public function getFiles()
{
return $this->files;
@ -135,25 +139,30 @@ class IcingaConfig
return $result;
}
/**
* @return string
*/
public function getFileNames()
{
return array_keys($this->files);
}
/**
* @param string $name
*
* @return IcingaConfigFile
*/
public function getFile($name)
{
return $this->files[$name];
}
public function getMissingFiles($missing)
{
$files = array();
foreach ($this->files as $name => $file) {
$files[] = $name . '=' . $file->getChecksum();
}
return $files;
}
/**
* @param string $checksum
* @param Db $connection
*
* @return static
*/
public static function load($checksum, Db $connection)
{
$config = new static($connection);
@ -161,6 +170,12 @@ class IcingaConfig
return $config;
}
/**
* @param string $checksum
* @param Db $connection
*
* @return bool
*/
public static function exists($checksum, Db $connection)
{
$db = $connection->getDbAdapter();
@ -211,6 +226,11 @@ class IcingaConfig
return $db->fetchOne($query) === $checksum;
}
/**
* @param Db $connection
*
* @return mixed
*/
public static function generate(Db $connection)
{
$config = new static($connection);
@ -317,15 +337,17 @@ class IcingaConfig
{
if (! array_key_exists($id, $this->zoneMap)) {
$zone = IcingaZone::loadWithAutoIncId($id, $this->connection);
$this->zoneMap[$id] = $zone->object_name;
$this->zoneMap[$id] = $zone->get('object_name');
}
return $this->zoneMap[$id];
}
/**
* @return self
*/
public function store()
{
$fileTable = IcingaConfigFile::$table;
$fileKey = IcingaConfigFile::$keyName;
@ -393,6 +415,11 @@ class IcingaConfig
return $this;
}
/**
* @throws IcingaException
*
* @return self
*/
protected function generateFromDb()
{
PrefetchCache::initialize($this->connection);
@ -445,6 +472,9 @@ class IcingaConfig
return $this;
}
/**
* @return self
*/
protected function prepareGlobalBasics()
{
if ($this->isLegacy()) {
@ -553,6 +583,13 @@ apply Service for (title => params in host.vars["%s"]) {
return $db->fetchOne($query);
}
/**
* @param string $checksum
*
* @throws NotFoundError
*
* @return self
*/
protected function loadFromDb($checksum)
{
$query = $this->db->select()->from(
@ -562,11 +599,11 @@ apply Service for (title => params in host.vars["%s"]) {
$result = $this->db->fetchRow($query);
if (empty($result)) {
throw new Exception(sprintf('Got no config for %s', Util::binary2hex($checksum)));
throw new NotFoundError('Got no config for %s', Util::binary2hex($checksum));
}
$this->checksum = $this->binFromDb($result->checksum);
$this->duration = $result->duration;
$this->generationTime = $result->duration;
$this->lastActivityChecksum = $this->binFromDb($result->last_activity_checksum);
$query = $this->db->select()->from(
@ -597,12 +634,19 @@ apply Service for (title => params in host.vars["%s"]) {
protected function createFileFromDb($type)
{
/** @var IcingaObject $class */
$class = 'Icinga\\Module\\Director\\Objects\\Icinga' . ucfirst($type);
Benchmark::measure(sprintf('Prefetching %s', $type));
$objects = $class::prefetchAll($this->connection);
return $this->createFileForObjects($type, $objects);
}
/**
* @param string $type Short object type, like 'service' or 'zone'
* @param IcingaObject[] $objects
*
* @return self
*/
protected function createFileForObjects($type, $objects)
{
if (empty($objects)) {
@ -613,7 +657,7 @@ apply Service for (title => params in host.vars["%s"]) {
foreach ($objects as $object) {
if ($object->isExternal()) {
if ($type === 'zone') {
$this->zoneMap[$object->id] = $object->object_name;
$this->zoneMap[$object->get('id')] = $object->getObjectName();
}
}
@ -650,6 +694,12 @@ apply Service for (title => params in host.vars["%s"]) {
return in_array($type, $types);
}
/**
* @param string $name Relative config file name
* @param string $suffix Config file suffix, defaults to '.conf'
*
* @return IcingaConfigFile
*/
public function configFile($name, $suffix = '.conf')
{
$filename = $name . $suffix;
@ -662,6 +712,7 @@ apply Service for (title => params in host.vars["%s"]) {
protected function collectExtraFiles()
{
/** @var ShipConfigFilesHook $hook */
foreach (Hook::all('Director\\ShipConfigFiles') as $hook) {
foreach ($hook->fetchFiles() as $filename => $file) {
if (array_key_exists($filename, $this->files)) {

View File

@ -21,6 +21,11 @@ class IcingaConfigFile
protected $cntApply = 0;
/**
* @param $content
*
* @return self
*/
public function prepend($content)
{
$this->content = $content . $this->content;

View File

@ -187,7 +187,6 @@ class IcingaConfigHelper
}
$parts = preg_split('/\s+/', $interval, -1, PREG_SPLIT_NO_EMPTY);
$value = 0;
foreach ($parts as $part) {
if (! preg_match('/^(\d+)([dhms]?)$/', $part)) {
return false;
@ -242,7 +241,6 @@ class IcingaConfigHelper
return '0s';
}
$parts = array();
$steps = array(
'd' => 86400,
'h' => 3600,

View File

@ -3,7 +3,6 @@
namespace Icinga\Module\Director\Job;
use Exception;
use Icinga\Application\Benchmark;
use Icinga\Exception\IcingaException;
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
use Icinga\Module\Director\Hook\JobHook;
@ -129,9 +128,14 @@ class ConfigJob extends JobHook
public function getRemainingGraceTime()
{
if ($this->isWithinGracePeriod()) {
return $deployment->getDeploymentTimestamp()
if ($deployment = $this->lastDeployment()) {
return $deployment->getDeploymentTimestamp()
+ $this->getSetting('grace_period')
- time();
} else {
return null;
}
}
return 0;

View File

@ -2,9 +2,9 @@
namespace Icinga\Module\Director\Job;
use Exception;
use Icinga\Module\Director\Hook\JobHook;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Module\Director\Web\Form\QuickForm;
class ImportJob extends JobHook
@ -72,6 +72,7 @@ class ImportJob extends JobHook
protected static function enumImportSources(QuickForm $form)
{
/** @var DirectorObjectForm $form */
$db = $form->getDb();
$query = $db->select()->from(
'import_source',

View File

@ -2,8 +2,8 @@
namespace Icinga\Module\Director\Job;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Hook\JobHook;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Module\Director\Web\Form\QuickForm;
use Icinga\Module\Director\Objects\SyncRule;
@ -42,6 +42,7 @@ class SyncJob extends JobHook
public static function addSettingsFormFields(QuickForm $form)
{
/** @var DirectorObjectForm $form */
$rules = self::enumSyncRules($form);
$form->addElement('select', 'rule_id', array(
@ -84,6 +85,7 @@ class SyncJob extends JobHook
protected static function enumSyncRules(QuickForm $form)
{
/** @var DirectorObjectForm $form */
$db = $form->getDb();
$query = $db->select()->from('sync_rule', array('id', 'rule_name'))->order('rule_name');
$res = $db->fetchPairs($query);

View File

@ -133,6 +133,10 @@ class KickstartHelper
return $this->apiUser;
}
/**
* @throws ConfigurationError
* @return self
*/
protected function loadZones()
{
$db = $this->db;

View File

@ -18,7 +18,7 @@ class Monitoring
}
if ($modules->hasLoaded('monitoring')) {
$this->backend = MonitoringBackend::createBackend();
$this->backend = MonitoringBackend::instance();
}
}

View File

@ -4,8 +4,9 @@ namespace Icinga\Module\Director\Objects;
use Icinga\Module\Director\Data\Db\DbObjectWithSettings;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Web\Form\QuickBaseForm;
use Icinga\Module\Director\Hook\DataTypeHook;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Zend_Form_Element as ZfElement;
class DirectorDatafield extends DbObjectWithSettings
{
@ -60,12 +61,12 @@ class DirectorDatafield extends DbObjectWithSettings
$this->required = (bool) $value;
}
public function getFormElement(QuickBaseForm $form, $name = null)
public function getFormElement(DirectorObjectForm $form, $name = null)
{
$className = $this->datatype;
$className = $this->get('datatype');
if ($name === null) {
$name = 'var_' . $this->varname;
$name = 'var_' . $this->get('varname');
}
if (! class_exists($className)) {
@ -76,16 +77,17 @@ class DirectorDatafield extends DbObjectWithSettings
return $el;
}
/** @var DataTypeHook $datatype */
$datatype = new $className;
$datatype->setSettings($this->getSettings());
$el = $datatype->getFormElement($name, $form);
if ($this->caption) {
$el->setLabel($this->caption);
if ($caption = $this->get('caption')) {
$el->setLabel($caption);
}
if ($this->description) {
$el->setDescription($this->description);
if ($description = $this->get('description')) {
$el->setDescription($description);
}
$this->applyObjectData($el, $form);
@ -93,7 +95,7 @@ class DirectorDatafield extends DbObjectWithSettings
return $el;
}
protected function applyObjectData($el, $form)
protected function applyObjectData(ZfElement $el, DirectorObjectForm $form)
{
$object = $form->getObject();
if ($object instanceof IcingaObject) {
@ -101,7 +103,7 @@ class DirectorDatafield extends DbObjectWithSettings
$el->setRequired(false);
}
$varname = $this->varname;
$varname = $this->get('varname');
$form->setInheritedValue(
$el,

View File

@ -41,10 +41,13 @@ class IcingaEndpoint extends IcingaObject
);
}
/**
* @return CoreApi
*/
public function api()
{
$client = new RestApiClient(
$this->getResolvedProperty('host', $this->object_name),
$this->getResolvedProperty('host', $this->getObjectName()),
$this->getResolvedProperty('port')
);

View File

@ -2,20 +2,22 @@
namespace Icinga\Module\Director\Objects;
use Exception;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filter\FilterChain;
use Icinga\Data\Filter\FilterExpression;
use Icinga\Exception\ProgrammingError;
use Icinga\Module\Director\CustomVariable\CustomVariables;
use Icinga\Module\Director\IcingaConfig\AssignRenderer;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Db\Cache\PrefetchCache;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Exception\NestingError;
use Icinga\Module\Director\IcingaConfig\ExtensibleSet;
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1;
use Icinga\Data\Filter\Filter;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\ProgrammingError;
use Exception;
abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
{
@ -100,18 +102,20 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
*/
protected $intervalProperties = array();
/** @var Db */
protected $connection;
private $vars;
private $groups;
private $imports;
/** @var IcingaTimePeriodRanges - TODO: generic ranges */
private $ranges;
private $arguments;
private $assignments;
private $shouldBeRemoved = false;
private $resolveCache = array();
@ -120,6 +124,14 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
private $templateResolver;
/**
* @return Db
*/
public function getConnection()
{
return $this->connection;
}
public function propertyIsBoolean($property)
{
return array_key_exists($property, $this->booleans);
@ -232,6 +244,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
protected function getRelatedSet($property)
{
if (! array_key_exists($property, $this->loadedRelatedSets)) {
/** @var ExtensibleSet $class */
$class = $this->getRelatedSetClass($property);
$this->loadedRelatedSets[$property]
= $class::forIcingaObject($this, $property);
@ -286,6 +299,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
protected function getRelatedObject($property, $id)
{
/** @var IcingaObject $class */
$class = $this->getRelationClass($property);
return $class::loadWithAutoIncId($id, $this->connection);
}
@ -398,12 +412,18 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
/**
* @codingStandardsIgnoreStart
*
* @param Filter|string $filter
*
* @throws ProgrammingError
*
* @return self
*/
public function setAssign_filter($filter)
{
if (! $this->supportsAssignments() && $filter !== null) {
if ($this->hasProperty('object_type')) {
$type = $this->object_type;
$type = $this->get('object_type');
} else {
$type = get_class($this);
}
@ -444,13 +464,14 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
protected function resolveUnresolvedRelatedProperty($name)
{
$short = substr($name, 0, -3);
/** @var IcingaObject $class */
$class = $this->getRelationClass($short);
$object = $class::load(
$this->unresolvedRelatedProperties[$name],
$this->connection
);
$this->reallySet($name, $object->id);
$this->reallySet($name, $object->get('id'));
unset($this->unresolvedRelatedProperties[$name]);
}
@ -515,9 +536,10 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
}
if ($id = $this->get($idKey)) {
/** @var IcingaObject $class */
$class = $this->getRelationClass($key);
$object = $class::loadWithAutoIncId($id, $this->connection);
return $object->object_name;
return $object->get('object_name');
}
return null;
@ -688,7 +710,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
public function isDisabled()
{
return $this->disabled === 'y';
return $this->get('disabled') === 'y';
}
public function markForRemoval($remove = true)
@ -716,10 +738,14 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this->groups;
}
/**
* @return IcingaTimePeriodRanges
*/
public function ranges()
{
$this->assertRangesSupport();
if ($this->ranges === null) {
/** @var IcingaTimePeriodRanges $class */
$class = $this->getRangeClass();
if ($this->hasBeenLoadedFromDb()) {
$this->ranges = $class::loadForStoredObject($this);
@ -1017,7 +1043,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
$query = $db->select()->from(
array('oi' => $table . '_inheritance'),
array('cnt' => 'COUNT(*)')
)->where('oi.parent_' . $type . '_id = ?', (int) $this->id);
)->where('oi.parent_' . $type . '_id = ?', (int) $this->get('id'));
return $db->fetchOne($query);
}
@ -1095,6 +1121,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
{
// TODO: speed up by passing only desired properties (filter columns) to
// toPlainObject method
/** @var FilterChain|FilterExpression $filter */
return $filter->matches($this->toPlainObject());
}
@ -1216,7 +1243,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
array('f' => $this->getTableName() . '_field'),
'df.id = f.datafield_id',
array()
)->where('f.' . $this->getShortTableName() . '_id = ?', (int) $this->id)
)->where('f.' . $this->getShortTableName() . '_id = ?', (int) $this->get('id'))
->order('df.caption ASC');
$res = $db->fetchAll($query);
@ -1244,25 +1271,25 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
public function isObject()
{
return $this->hasProperty('object_type')
&& $this->object_type === 'object';
&& $this->get('object_type') === 'object';
}
public function isTemplate()
{
return $this->hasProperty('object_type')
&& $this->object_type === 'template';
&& $this->get('object_type') === 'template';
}
public function isExternal()
{
return $this->hasProperty('object_type')
&& $this->object_type === 'external_object';
&& $this->get('object_type') === 'external_object';
}
public function isApplyRule()
{
return $this->hasProperty('object_type')
&& $this->object_type === 'apply';
&& $this->get('object_type') === 'apply';
}
protected function storeRelatedObjects()
@ -1294,6 +1321,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
$this->storeRelatedObjects();
}
/**
* @return self
*/
protected function storeCustomVars()
{
if ($this->supportsCustomVars()) {
@ -1303,6 +1333,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this;
}
/**
* @return self
*/
protected function storeGroups()
{
if ($this->supportsGroups()) {
@ -1312,6 +1345,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this;
}
/**
* @return self
*/
protected function storeMultiRelations()
{
foreach ($this->loadedMultiRelations as $rel) {
@ -1321,6 +1357,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this;
}
/**
* @return self
*/
protected function storeRanges()
{
if ($this->supportsRanges()) {
@ -1330,6 +1369,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this;
}
/**
* @return self
*/
protected function storeArguments()
{
if ($this->supportsArguments()) {
@ -1339,6 +1381,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this;
}
/**
* @return self
*/
protected function storeRelatedSets()
{
foreach ($this->loadedRelatedSets as $set) {
@ -1350,6 +1395,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this;
}
/**
* @return self
*/
protected function storeImports()
{
if ($this->supportsImports()) {
@ -1379,7 +1427,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
$config = new IcingaConfig($this->connection);
$object = $this;
if ($object->isExternal()) {
$object->object_type = 'object';
$object->set('object_type', 'object');
$wasExternal = true;
} else {
$wasExternal = false;
@ -1396,7 +1444,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
);
}
if ($wasExternal) {
$object->object_type = 'external_object';
$object->set('object_type', 'external_object');
}
return $config;
@ -1416,10 +1464,10 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
if ($this->getResolvedProperty('zone_id')) {
$a = clone($this);
$a->enable_active_checks = true;
$a->set('enable_active_checks', true);
$b = clone($this);
$a->enable_active_checks = false;
$a->set('enable_active_checks', false);
$config->configFile(
'director/master/' . $filename,
@ -1448,7 +1496,8 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
public function renderToConfig(IcingaConfig $config)
{
if ($config->isLegacy()) {
return $this->renderToLegacyConfig($config);
$this->renderToLegacyConfig($config);
return;
}
if ($this->isExternal()) {
@ -1478,12 +1527,12 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
public function getRenderingZone(IcingaConfig $config = null)
{
if ($this->hasUnresolvedRelatedProperty('zone_id')) {
return $this->zone;
return $this->get('zone');
}
if ($this->hasProperty('zone_id')) {
if (! $this->supportsImports()) {
if ($zoneId = $this->zone_id) {
if ($zoneId = $this->get('zone_id')) {
// Config has a lookup cache, is faster:
return $config->getZoneName($zoneId);
}
@ -1549,7 +1598,11 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
*/
protected function renderLegacyHost_id()
{
return $this->renderLegacyRelationProperty('host', $this->host_id, 'host_name');
return $this->renderLegacyRelationProperty(
'host',
$this->get('host_id'),
'host_name'
);
}
protected function renderLegacyTimeout()
@ -1670,8 +1723,6 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
$short, // NOT
c::renderString($this->$short)
);
return '';
}
}
@ -1725,8 +1776,6 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
$short, // NOT
c1::renderString($this->$short)
);
return '';
}
}
@ -1936,7 +1985,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
{
// @codingStandardsIgnoreEnd
return ' ' . AssignRenderer::forFilter(
Filter::fromQueryString($this->assign_filter)
Filter::fromQueryString($this->get('assign_filter'))
)->renderAssign() . "\n";
}
@ -2042,13 +2091,16 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
}
}
protected function getObjectName()
public function getObjectName()
{
if ($this->hasProperty('object_name')) {
return $this->object_name;
return $this->get('object_name');
} else {
// TODO: replace with an exception once finished
return 'ERROR: NO NAME';
throw new ProgrammingError(
'Trying to access "object_name" for an instance of "%s"',
get_class($this)
);
}
}
@ -2081,20 +2133,44 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return 'Icinga\\Module\\Director\\Objects\\' . $prefix . ucfirst($type);
}
/**
* @param $type
* @param array $properties
* @param Db|null $db
*
* @return IcingaObject
*/
public static function createByType($type, $properties = array(), Db $db = null)
{
/** @var IcingaObject $class */
$class = self::classByType($type);
return $class::create($properties, $db);
}
/**
* @param $type
* @param $id
* @param Db $db
*
* @return IcingaObject
*/
public static function loadByType($type, $id, Db $db)
{
/** @var IcingaObject $class */
$class = self::classByType($type);
return $class::load($id, $db);
}
/**
* @param $type
* @param $id
* @param Db $db
*
* @return bool
*/
public static function existsByType($type, $id, Db $db)
{
/** @var IcingaObject $class */
$class = self::classByType($type);
return $class::exists($id, $db);
}
@ -2162,6 +2238,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
if ($object->supportsCustomVars()) {
$myVars = $this->vars();
/** @var CustomVariables $vars */
foreach ($vars as $key => $var) {
$myVars->set($key, $var);
}
@ -2336,21 +2413,21 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
{
$params = array();
if ($this->object_type === 'apply') {
$params['id'] = $this->id;
if ($this->isApplyRule()) {
$params['id'] = $this->get('id');
} else {
$params = array('name' => $this->object_name);
$params = array('name' => $this->getObjectName());
if ($this->hasProperty('host_id') && $this->host_id) {
$params['host'] = $this->host;
if ($this->hasProperty('host_id') && $this->get('host_id')) {
$params['host'] = $this->get('host');
}
if ($this->hasProperty('service_id') && $this->service_id) {
$params['service'] = $this->service;
if ($this->hasProperty('service_id') && $this->get('service_id')) {
$params['service'] = $this->get('service');
}
if ($this->hasProperty('service_set_id') && $this->service_set_id) {
$params['set'] = $this->service_set;
if ($this->hasProperty('service_set_id') && $this->get('service_set_id')) {
$params['set'] = $this->get('service_set');
}
}
@ -2393,7 +2470,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
}
}
if ($this->differsFromDefaultvalue($k, $v)) {
if ($this->differsFromDefaultValue($k, $v)) {
$props[$k] = $v;
}
}

View File

@ -4,7 +4,6 @@ namespace Icinga\Module\Director\Objects;
use Countable;
use Exception;
use Icinga\Exception\ProgrammingError;
use Iterator;
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
@ -14,7 +13,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
{
protected $storedNames = array();
/** @var Array A list of our imports, key and value are the import name */
/** @var array A list of our imports, key and value are the import name */
protected $imports = array();
/** @var IcingaObject[] A list of all objects we have seen, referred by name */
@ -134,6 +133,8 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
/**
* Magic isset check
*
* @param string $import
*
* @return boolean
*/
public function __isset($import)
@ -209,6 +210,9 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
return $this;
}
/**
* @return IcingaObject[]
*/
public function getObjects()
{
$list = array();
@ -226,6 +230,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
}
$connection = $this->object->getConnection();
/** @var IcingaObject $class */
$class = $this->getImportClass();
if (is_array($this->object->getKeyName())) {
// Services only
@ -240,7 +245,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
$import = $class::load($name, $connection);
}
return $this->objects[$import->object_name] = $import;
return $this->objects[$import->getObjectName()] = $import;
}
protected function getImportTableName()
@ -284,15 +289,16 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
return true;
}
$objectId = (int) $this->object->id;
$objectId = (int) $this->object->get('id');
$type = $this->getType();
$objectCol = $type . '_id';
$importCol = 'parent_' . $type . '_id';
$table = $this->getImportTableName();
$db = $this->object->getDb();
if ($this->object->hasBeenLoadedFromDb()) {
$this->object->db->delete(
$db->delete(
$table,
$objectCol . ' = ' . $objectId
);
@ -300,11 +306,11 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
$weight = 1;
foreach ($this->getObjects() as $import) {
$this->object->db->insert(
$db->insert(
$table,
array(
$objectCol => $objectId,
$importCol => $import->id,
$importCol => $import->get('id'),
'weight' => $weight++
)
);

View File

@ -24,18 +24,16 @@ class IcingaTimePeriodRange extends DbObject
$now = time();
}
if (false === ($wday = $this->getWeekDay($this->range_key))) {
if (false === ($weekDay = $this->getWeekDay($this->get('range_key')))) {
// TODO, dates are not yet supported
return false;
}
$wdayName = $this->range_key;
if ((int) strftime('%w', $now) !== $wday) {
if ((int) strftime('%w', $now) !== $weekDay) {
return false;
}
$timeRanges = preg_split('/\s*,\s*/', $this->range_value, -1, PREG_SPLIT_NO_EMPTY);
$timeRanges = preg_split('/\s*,\s*/', $this->get('range_value'), -1, PREG_SPLIT_NO_EMPTY);
foreach ($timeRanges as $timeRange) {
if ($this->timeRangeIsActive($timeRange, $now)) {
return true;
@ -47,6 +45,7 @@ class IcingaTimePeriodRange extends DbObject
protected function timeRangeIsActive($rangeString, $now)
{
$hBegin = $mBegin = $hEnd = $mEnd = null;
if (sscanf($rangeString, '%2d:%2d-%2d:%2d', $hBegin, $mBegin, $hEnd, $mEnd) === 4) {
if ($this->timeFromHourMin($hBegin, $mBegin, $now) <= $now
&& $this->timeFromHourMin($hEnd, $mEnd, $now) >= $now

View File

@ -33,12 +33,14 @@ class SyncRule extends DbObject
private $purgeStrategy;
/** @var int */
private $currentSyncRunId;
private $filter;
private $hasCombinedKey;
/** @var SyncProperty[] */
private $syncProperties;
private $sourceKeyPattern;
@ -57,7 +59,7 @@ class SyncRule extends DbObject
$db->select()
->from(array('p' => 'sync_property'), 'p.source_id')
->join(array('s' => 'import_source'), 's.id = p.source_id', array())
->where('rule_id = ?', $this->id)
->where('rule_id = ?', $this->get('id'))
->order('s.source_name')
)
));
@ -84,7 +86,7 @@ class SyncRule extends DbObject
$query = $db->select()->from(
array('sr' => 'sync_run'),
'sr.start_time'
)->where('sr.rule_id = ?', $this->id)
)->where('sr.rule_id = ?', $this->get('id'))
->order('sr.start_time DESC')
->limit(1);
@ -101,7 +103,7 @@ class SyncRule extends DbObject
$query = $db->select()->from(
array('sr' => 'sync_run'),
'sr.id'
)->where('sr.rule_id = ?', $this->id)
)->where('sr.rule_id = ?', $this->get('id'))
->order('sr.start_time DESC')
->limit(1);
@ -120,13 +122,13 @@ class SyncRule extends DbObject
->from(
array('p' => 'sync_property'),
array('priority' => '(CASE WHEN MAX(p.priority) IS NULL THEN 1 ELSE MAX(p.priority) + 1 END)')
)->where('p.rule_id = ?', $this->id)
)->where('p.rule_id = ?', $this->get('id'))
);
}
public function matches($row)
{
if ($this->filter_expression === null) {
if ($this->get('filter_expression') === null) {
return true;
}
@ -137,31 +139,31 @@ class SyncRule extends DbObject
{
$hadChanges = false;
Benchmark::measure('Checking sync rule ' . $this->rule_name);
Benchmark::measure('Checking sync rule ' . $this->get('rule_name'));
try {
$this->last_attempt = date('Y-m-d H:i:s');
$this->sync_state = 'unknown';
$this->set('last_attempt', date('Y-m-d H:i:s'));
$this->set('sync_state', 'unknown');
$sync = $this->sync();
if ($sync->hasModifications()) {
Benchmark::measure('Got modifications for sync rule ' . $this->rule_name);
$this->sync_state = 'pending-changes';
Benchmark::measure('Got modifications for sync rule ' . $this->get('rule_name'));
$this->set('sync_state', 'pending-changes');
if ($apply && $runId = $sync->apply()) {
Benchmark::measure('Successfully synced rule ' . $this->rule_name);
$this->sync_state = 'in-sync';
Benchmark::measure('Successfully synced rule ' . $this->get('rule_name'));
$this->set('sync_state', 'in-sync');
$this->currentSyncRunId = $runId;
}
$hadChanges = true;
} else {
Benchmark::measure('No modifications for sync rule ' . $this->rule_name);
$this->sync_state = 'in-sync';
Benchmark::measure('No modifications for sync rule ' . $this->get('rule_name'));
$this->set('sync_state', 'in-sync');
}
$this->last_error_message = null;
$this->set('last_error_message', null);
} catch (Exception $e) {
$this->sync_state = 'failing';
$this->last_error_message = $e->getMessage();
$this->set('sync_state', 'failing');
$this->set('last_error_message', $e->getMessage());
// TODO: Store last error details / trace?
}
@ -172,6 +174,9 @@ class SyncRule extends DbObject
return $hadChanges;
}
/**
* @return IcingaObject[]
*/
public function getExpectedModifications()
{
return $this->sync()->getExpectedModifications();
@ -217,7 +222,7 @@ class SyncRule extends DbObject
protected function filter()
{
if ($this->filter === null) {
$this->filter = Filter::fromQueryString($this->filter_expression);
$this->filter = Filter::fromQueryString($this->get('filter_expression'));
}
return $this->filter;
@ -235,7 +240,7 @@ class SyncRule extends DbObject
// TODO: Allow for more
protected function loadConfiguredPurgeStrategy()
{
if ($this->purge_existing === 'y') {
if ($this->get('purge_existing') === 'y') {
return PurgeStrategy::load('ImportRunBased', $this);
} else {
return PurgeStrategy::load('PurgeNothing', $this);
@ -254,7 +259,7 @@ class SyncRule extends DbObject
$this->hasCombinedKey = false;
// TODO: Move to Objects
if ($this->object_type === 'service') {
if ($this->get('object_type') === 'service') {
$hasHost = false;
$hasObjectName = false;
@ -277,7 +282,7 @@ class SyncRule extends DbObject
$this->destinationKeyPattern = '${host}!${object_name}';
}
} elseif ($this->object_type === 'datalistEntry') {
} elseif ($this->get('object_type') === 'datalistEntry') {
$hasList = false;
$hasName = false;
@ -323,14 +328,13 @@ class SyncRule extends DbObject
public function fetchSyncProperties()
{
$db = $this->getDb();
return SyncProperty::loadAll(
$this->getConnection(),
$db->select()
->from('sync_property')
->where('rule_id = ?', $this->id)
->where('rule_id = ?', $this->get('id'))
->order('priority DESC')
);
return $this->syncProperties;
}
}

View File

@ -59,7 +59,7 @@ class Settings
$db = $this->db;
if ($value === null) {
$updated = $db->delete(
$db->delete(
'director_setting',
$db->quoteInto('setting_name = ?', $name)
);

View File

@ -46,6 +46,9 @@ class Util
* @param int $length Desired key length
* @param bool $raw Returns the binary key if true, hex string otherwise
*
* @throws NotImplementedError when asking for an unsupported algorightm
* @throws ProgrammingError when passing invalid parameters
*
* @return string A $length byte long key, derived from secret and salt
*/
public static function pbkdf2($alg, $secret, $salt, $iterations, $length, $raw = false)
@ -142,7 +145,7 @@ class Util
{
$resources = array();
foreach (ResourceFactory::getResourceConfigs() as $name => $resource) {
if ($resource->type === $type && self::resourceIsAllowed($name)) {
if ($resource->get('type') === $type && self::resourceIsAllowed($name)) {
$resources[$name] = $name;
}
}

View File

@ -2,27 +2,33 @@
namespace Icinga\Module\Director\Web\Controller;
use Icinga\Application\Icinga;
use Icinga\Data\Paginatable;
use Icinga\Exception\AuthenticationException;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Director\Core\CoreApi;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Monitoring;
use Icinga\Module\Director\Objects\IcingaEndpoint;
use Icinga\Module\Director\Web\Form\FormLoader;
use Icinga\Module\Director\Web\Form\QuickBaseForm;
use Icinga\Module\Director\Web\Form\QuickForm;
use Icinga\Module\Director\Web\Table\QuickTable;
use Icinga\Module\Director\Web\Table\TableLoader;
use Icinga\Web\Controller;
use Icinga\Web\Widget;
abstract class ActionController extends Controller
{
/** @var Db */
protected $db;
protected $isApified = false;
/** @var CoreApi */
private $api;
/** @var Monitoring */
private $monitoring;
public function init()
@ -53,6 +59,11 @@ abstract class ActionController extends Controller
return $paginatable;
}
/**
* @param string $name
*
* @return QuickBaseForm
*/
public function loadForm($name)
{
$form = FormLoader::load($name, $this->Module());
@ -64,6 +75,11 @@ abstract class ActionController extends Controller
return $form;
}
/**
* @param string $name
*
* @return QuickTable
*/
public function loadTable($name)
{
return TableLoader::load($name, $this->Module());
@ -226,8 +242,6 @@ abstract class ActionController extends Controller
default:
return 'An error occured when parsing a JSON string';
}
return $this;
}
protected function getApiIfAvailable()
@ -257,6 +271,11 @@ abstract class ActionController extends Controller
return $this->api;
}
/**
* @throws ConfigurationError
*
* @return Db
*/
protected function db()
{
if ($this->db === null) {
@ -265,7 +284,7 @@ abstract class ActionController extends Controller
$this->db = Db::fromResourceName($resourceName);
} else {
if ($this->getRequest()->isApiRequest()) {
throw new ConfigError('Icinga Director is not correctly configured');
throw new ConfigurationError('Icinga Director is not correctly configured');
} else {
$this->redirectNow('director');
}
@ -275,6 +294,9 @@ abstract class ActionController extends Controller
return $this->db;
}
/**
* @return Monitoring
*/
protected function monitoring()
{
if ($this->monitoring === null) {

View File

@ -3,15 +3,20 @@
namespace Icinga\Module\Director\Web\Form;
use Exception;
use Icinga\Module\Director\Core\CoreApi;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Data\Db\DbObjectWithSettings;
use Icinga\Module\Director\Exception\NestingError;
use Icinga\Module\Director\IcingaConfig\StateFilterSet;
use Icinga\Module\Director\IcingaConfig\TypeFilterSet;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Objects\DirectorDatafield;
use Zend_Form_Element_Select as Zf_Select;
use Zend_Form_Element as ZfElement;
use Zend_Form_Element_Select as ZfSelect;
abstract class DirectorObjectForm extends QuickForm
{
/** @var Db */
protected $db;
/** @var IcingaObject */
@ -37,6 +42,7 @@ abstract class DirectorObjectForm extends QuickForm
private $allowsExperimental;
/** @var CoreApi */
private $api;
public function setPreferredObjectType($type)
@ -45,9 +51,15 @@ abstract class DirectorObjectForm extends QuickForm
return $this;
}
/**
* @param array $values
*
* @return DbObject|DbObjectWithSettings|IcingaObject
*/
protected function object($values = array())
{
if ($this->object === null) {
/** @var DbObject|IcingaObject $class */
$class = $this->getObjectClassname();
if ($this->preferredObjectType && ! array_key_exists('object_type', $values)) {
$values['object_type'] = $this->preferredObjectType;
@ -87,7 +99,7 @@ abstract class DirectorObjectForm extends QuickForm
if ($this->hasBeenSent()) {
if ($el = $this->getElement('imports')) {
$this->populate($this->getRequest()->getPost());
$object->imports = $el->getValue();
$object->set('imports', $el->getValue());
}
}
@ -120,7 +132,7 @@ abstract class DirectorObjectForm extends QuickForm
}
// TODO: move to a subform
protected function handleRanges($object, & $values)
protected function handleRanges(IcingaObject $object, & $values)
{
if (! $object->supportsRanges()) {
return;
@ -203,7 +215,7 @@ abstract class DirectorObjectForm extends QuickForm
return $this->displayGroups[$group];
}
protected function handleProperties($object, & $values)
protected function handleProperties(DbObject $object, & $values)
{
$resolve = $this->assertResolvedImports();
if ($this->hasBeenSent()) {
@ -243,7 +255,7 @@ abstract class DirectorObjectForm extends QuickForm
}
}
protected function showInheritedProperties($object)
protected function showInheritedProperties(IcingaObject $object)
{
$inherited = $object->getInheritedProperties();
$origins = $object->getOriginsProperties();
@ -311,6 +323,9 @@ abstract class DirectorObjectForm extends QuickForm
}
}
/**
* @return self
*/
protected function groupMainProperties()
{
$elements = array(
@ -378,14 +393,14 @@ abstract class DirectorObjectForm extends QuickForm
}
}
public function setInheritedValue($el, $inherited, $inheritedFrom)
public function setInheritedValue(ZfElement $el, $inherited, $inheritedFrom)
{
if ($inherited === null) {
return;
}
$txtInherited = ' ' . $this->translate(' (inherited from "%s")');
if ($el instanceof Zf_Select) {
if ($el instanceof ZfSelect) {
$multi = $el->getMultiOptions();
if (is_bool($inherited)) {
$inherited = $inherited ? 'y' : 'n';
@ -425,7 +440,7 @@ abstract class DirectorObjectForm extends QuickForm
$object->hasBeenLoadedFromDb()
? $this->translate('The %s has successfully been stored')
: $this->translate('A new %s has successfully been created'),
$this->translate($this->getObjectName())
$this->translate($this->getObjectShortClassName())
);
$object->store($this->db);
} else {
@ -436,7 +451,7 @@ abstract class DirectorObjectForm extends QuickForm
}
if ($object instanceof IcingaObject) {
$this->setSuccessUrl(
'director/' . strtolower($this->getObjectName()),
'director/' . strtolower($this->getObjectShortClassName()),
$object->getUrlParams()
);
}
@ -501,7 +516,7 @@ abstract class DirectorObjectForm extends QuickForm
return $this->className;
}
protected function getObjectname()
protected function getObjectShortClassName()
{
if ($this->objectName === null) {
$className = substr(strrchr(get_class($this), '\\'), 1);
@ -603,17 +618,16 @@ abstract class DirectorObjectForm extends QuickForm
protected function deleteObject($object)
{
$key = $object->getKeyName();
if ($object instanceof IcingaObject && $object->hasProperty('object_name')) {
$msg = sprintf(
'%s "%s" has been removed',
$this->translate($this->getObjectName()),
$object->object_name
$this->translate($this->getObjectShortClassName()),
$object->getObjectName()
);
} else {
$msg = sprintf(
'%s has been removed',
$this->translate($this->getObjectName())
$this->translate($this->getObjectShortClassName())
);
}
@ -756,6 +770,7 @@ abstract class DirectorObjectForm extends QuickForm
public function loadObject($id)
{
/** @var DbObject $class */
$class = $this->getObjectClassname();
$this->object = $class::load($id, $this->db);
@ -775,12 +790,15 @@ abstract class DirectorObjectForm extends QuickForm
));
}
/**
* @return Db
*/
public function getDb()
{
return $this->db;
}
public function setDb($db)
public function setDb(Db $db)
{
$this->db = $db;
if ($this->object !== null) {
@ -800,7 +818,7 @@ abstract class DirectorObjectForm extends QuickForm
protected function addObjectTypeElement()
{
if (!$this->isNew()) {
return;
return $this;
}
if ($this->preferredObjectType) {
@ -813,8 +831,7 @@ abstract class DirectorObjectForm extends QuickForm
if ($object->supportsImports()) {
$templates = $this->enumAllowedTemplates();
// TODO: getObjectname is a confusing method name
if (empty($templates) && $this->getObjectname() !== 'Command') {
if (empty($templates) && $this->getObjectShortClassName() !== 'Command') {
$types = array('template' => $this->translate('Template'));
} else {
$types = array(
@ -933,6 +950,11 @@ abstract class DirectorObjectForm extends QuickForm
return $this;
}
/**
* @param bool $force
*
* @return self
*/
protected function addCheckCommandElements($force = false)
{
if (! $force && ! $this->isTemplate()) {
@ -942,12 +964,12 @@ abstract class DirectorObjectForm extends QuickForm
$this->addElement('select', 'check_command_id', array(
'label' => $this->translate('Check command'),
'description' => $this->translate('Check command definition'),
'multiOptions' => $this->optionalEnum($this->db->enumCheckCommands()),
'multiOptions' => $this->optionalEnum($this->db->enumCheckcommands()),
'class' => 'autosubmit', // This influences fields
));
$this->addToCheckExecutionDisplayGroup('check_command_id');
$eventCommands = $this->db->enumEventCommands();
$eventCommands = $this->db->enumEventcommands();
if (! empty($eventCommands)) {
$this->addElement('select', 'event_command_id', array(
@ -1077,7 +1099,7 @@ abstract class DirectorObjectForm extends QuickForm
return array();
}
$id = $object->id;
$id = $object->get('id');
if (array_key_exists($id, $tpl)) {
unset($tpl[$id]);

View File

@ -11,11 +11,15 @@ abstract class QuickBaseForm extends Zend_Form
/**
* The Icinga module this form belongs to. Usually only set if the
* form is initialized through the FormLoader
*
* @var Module
*/
protected $icingaModule;
protected $icingaModuleName;
private $hintCount = 0;
public function __construct($options = null)
{
$this->callZfConstructor($this->handleOptions($options))
@ -118,6 +122,7 @@ abstract class QuickBaseForm extends Zend_Form
}
if (array_key_exists('icingaModule', $options)) {
/** @var Module icingaModule */
$this->icingaModule = $options['icingaModule'];
$this->icingaModuleName = $this->icingaModule->getName();
unset($options['icingaModule']);

View File

@ -3,10 +3,10 @@
namespace Icinga\Module\Director\Web\Form;
use Icinga\Application\Icinga;
use Icinga\Application\Modules\Module;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Notification;
use Icinga\Web\Request;
use Icinga\Web\Response;
use Icinga\Web\Url;
use Exception;
@ -52,6 +52,8 @@ abstract class QuickForm extends QuickBaseForm
protected $submitButtonName;
protected $deleteButtonName;
protected $fakeSubmitButtonName;
/**
@ -59,8 +61,6 @@ abstract class QuickForm extends QuickBaseForm
*/
protected $didSetup = false;
protected $hintCount = 0;
protected $isApiRequest = false;
public function __construct($options = null)
@ -273,7 +273,7 @@ abstract class QuickForm extends QuickBaseForm
$this->getSubmitLabel()
);
} else {
$this->hasBeenSubmitted === false;
$this->hasBeenSubmitted = false;
}
}
@ -350,7 +350,7 @@ abstract class QuickForm extends QuickBaseForm
return $this;
}
public function addException(Exception $e, $elementName = null, $withDetails = true)
public function addException(Exception $e, $elementName = null)
{
$file = preg_split('/[\/\\\]/', $e->getFile(), -1, PREG_SPLIT_NO_EMPTY);
$file = array_pop($file);
@ -424,7 +424,9 @@ abstract class QuickForm extends QuickBaseForm
protected function redirectAndExit($url)
{
Icinga::app()->getFrontController()->getResponse()->redirectAndExit($url);
/** @var Response $response */
$response = Icinga::app()->getFrontController()->getResponse();
$response->redirectAndExit($url);
}
protected function setHttpResponseCode($code)
@ -449,10 +451,15 @@ abstract class QuickForm extends QuickBaseForm
return $this;
}
/**
* @return Request
*/
public function getRequest()
{
if ($this->request === null) {
$this->setRequest(Icinga::app()->getFrontController()->getRequest());
/** @var Request $request */
$request = Icinga::app()->getFrontController()->getRequest();
$this->setRequest($request);
}
return $this->request;
}
@ -461,6 +468,7 @@ abstract class QuickForm extends QuickBaseForm
{
if ($this->hasBeenSent === null) {
/** @var Request $req */
if ($this->request === null) {
$req = Icinga::app()->getFrontController()->getRequest();
} else {
@ -472,7 +480,7 @@ abstract class QuickForm extends QuickBaseForm
$this->hasBeenSent = array_key_exists(self::ID, $post) &&
$post[self::ID] === $this->getName();
} else {
$this->hasBeenSent === false;
$this->hasBeenSent = false;
}
}

View File

@ -16,6 +16,8 @@ abstract class IcingaObjectTable extends QuickTable
case 'apply':
return 'icinga-apply';
}
return null;
}
protected function listTableClasses()

View File

@ -5,29 +5,34 @@ namespace Icinga\Module\Director\Web\Table;
use Icinga\Application\Icinga;
use Icinga\Data\Filter\FilterAnd;
use Icinga\Data\Filter\FilterChain;
use Icinga\Data\Filter\FilterExpression;
use Icinga\Data\Filter\FilterNot;
use Icinga\Data\Filter\FilterOr;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Selectable;
use Icinga\Data\Paginatable;
use Icinga\Exception\QueryException;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\PlainObjectRenderer;
use Icinga\Web\Request;
use Icinga\Web\Url;
use Icinga\Web\Widget;
use Icinga\Web\Widget\Paginator;
use stdClass;
use Zend_Db_Select as ZfDbSelect;
abstract class QuickTable implements Paginatable
{
protected $view;
/** @var Db */
protected $connection;
protected $limit;
protected $offset;
/** @var Filter */
protected $filter;
protected $enforcedFilters = array();
@ -160,11 +165,14 @@ abstract class QuickTable implements Paginatable
return $this;
}
/**
* @return ZfDbSelect
*/
abstract protected function getBaseQuery();
public function fetchData()
{
$db = $this->connection()->getConnection();
$db = $this->db();
$query = $this->getBaseQuery()->columns($this->getColumns());
if ($this->hasLimit() || $this->hasOffset()) {
@ -176,7 +184,7 @@ abstract class QuickTable implements Paginatable
return $db->fetchAll($query);
}
protected function applyFiltersToQuery($query)
protected function applyFiltersToQuery(ZfDbSelect $query)
{
$filter = null;
$enforced = $this->enforcedFilters;
@ -205,7 +213,7 @@ abstract class QuickTable implements Paginatable
public function count()
{
$db = $this->connection()->getConnection();
$db = $this->db();
$query = clone($this->getBaseQuery());
$query->reset('order')->columns(array('COUNT(*)'));
$this->applyFiltersToQuery($query);
@ -246,6 +254,7 @@ abstract class QuickTable implements Paginatable
return method_exists($this, 'renderAdditionalActions');
}
/** @return Db */
protected function connection()
{
// TODO: Fail if missing? Require connection in constructor?
@ -254,7 +263,7 @@ abstract class QuickTable implements Paginatable
protected function db()
{
return $this->connection()->getConnection();
return $this->connection()->getDbAdapter();
}
protected function renderTitles($row)
@ -373,7 +382,7 @@ abstract class QuickTable implements Paginatable
return $cols[$col];
}
protected function renderFilter($filter, $level = 0)
protected function renderFilter(Filter $filter, $level = 0)
{
$str = '';
if ($filter instanceof FilterChain) {
@ -407,6 +416,7 @@ abstract class QuickTable implements Paginatable
}
}
} else {
/** @var FilterExpression $filter */
$str .= $this->whereToSql(
$this->mapFilterColumn($filter->getColumn()),
$filter->getSign(),

View File

@ -8,6 +8,7 @@ use Icinga\Exception\ProgrammingError;
class TableLoader
{
/** @return QuickTable */
public static function load($name, Module $module = null)
{
if ($module === null) {
@ -23,6 +24,7 @@ class TableLoader
$file = sprintf('%s/%s/%s.php', rtrim($basedir, '/'), implode('/', $parts), $class);
if (file_exists($file)) {
require_once($file);
/** @var QuickTable $class */
$class = $ns . $class;
return new $class();
}