mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-27 07:44:05 +02:00
library: lot's of cleanup
This commit is contained in:
parent
c2d54f9de9
commit
35815e0dad
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\IcingaConfig;
|
namespace Icinga\Module\Director\IcingaConfig;
|
||||||
|
|
||||||
use Icinga\Exception\ProgrammingError;
|
use InvalidArgumentException;
|
||||||
|
|
||||||
class IcingaLegacyConfigHelper
|
class IcingaLegacyConfigHelper
|
||||||
{
|
{
|
||||||
@ -34,24 +34,24 @@ class IcingaLegacyConfigHelper
|
|||||||
} elseif ($value === 'n') {
|
} elseif ($value === 'n') {
|
||||||
return '0';
|
return '0';
|
||||||
} else {
|
} else {
|
||||||
throw new ProgrammingError('%s is not a valid boolean', $value);
|
throw new InvalidArgumentException('%s is not a valid boolean', $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Double-check legacy "encoding"
|
// TODO: Double-check legacy "encoding"
|
||||||
public static function renderString($string)
|
public static function renderString($string)
|
||||||
{
|
{
|
||||||
$special = array(
|
$special = [
|
||||||
'/\\\/',
|
'/\\\/',
|
||||||
'/\$/',
|
'/\$/',
|
||||||
'/\t/',
|
'/\t/',
|
||||||
'/\r/',
|
'/\r/',
|
||||||
'/\n/',
|
'/\n/',
|
||||||
// '/\b/', -> doesn't work
|
// '/\b/', -> doesn't work
|
||||||
'/\f/'
|
'/\f/',
|
||||||
);
|
];
|
||||||
|
|
||||||
$replace = array(
|
$replace = [
|
||||||
'\\\\\\',
|
'\\\\\\',
|
||||||
'\\$',
|
'\\$',
|
||||||
'\\t',
|
'\\t',
|
||||||
@ -59,17 +59,20 @@ class IcingaLegacyConfigHelper
|
|||||||
'\\n',
|
'\\n',
|
||||||
// '\\b',
|
// '\\b',
|
||||||
'\\f',
|
'\\f',
|
||||||
);
|
];
|
||||||
|
|
||||||
$string = preg_replace($special, $replace, $string);
|
$string = preg_replace($special, $replace, $string);
|
||||||
|
|
||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Requires an array
|
/**
|
||||||
|
* @param array $array
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public static function renderArray($array)
|
public static function renderArray($array)
|
||||||
{
|
{
|
||||||
$data = array();
|
$data = [];
|
||||||
foreach ($array as $entry) {
|
foreach ($array as $entry) {
|
||||||
if ($entry instanceof IcingaConfigRenderer) {
|
if ($entry instanceof IcingaConfigRenderer) {
|
||||||
// $data[] = $entry;
|
// $data[] = $entry;
|
||||||
|
@ -2,18 +2,20 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Objects;
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
use Icinga\Exception\ProgrammingError;
|
|
||||||
use Iterator;
|
|
||||||
use Countable;
|
use Countable;
|
||||||
|
use Exception;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use Iterator;
|
||||||
|
|
||||||
class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
||||||
{
|
{
|
||||||
protected $storedArguments = array();
|
/** @var IcingaCommandArgument[] */
|
||||||
|
protected $storedArguments = [];
|
||||||
|
|
||||||
/** @var IcingaCommandArgument[] */
|
/** @var IcingaCommandArgument[] */
|
||||||
protected $arguments = array();
|
protected $arguments = [];
|
||||||
|
|
||||||
protected $modified = false;
|
protected $modified = false;
|
||||||
|
|
||||||
@ -21,7 +23,7 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
private $position = 0;
|
private $position = 0;
|
||||||
|
|
||||||
protected $idx = array();
|
protected $idx = [];
|
||||||
|
|
||||||
public function __construct(IcingaObject $object)
|
public function __construct(IcingaObject $object)
|
||||||
{
|
{
|
||||||
@ -90,7 +92,7 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$argument->set('command_id', $this->object->id);
|
$argument->set('command_id', $this->object->get('id'));
|
||||||
|
|
||||||
$key = $argument->argument_name;
|
$key = $argument->argument_name;
|
||||||
if (array_key_exists($key, $this->arguments)) {
|
if (array_key_exists($key, $this->arguments)) {
|
||||||
@ -114,18 +116,18 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
protected function mungeCommandArgument($key, $value)
|
protected function mungeCommandArgument($key, $value)
|
||||||
{
|
{
|
||||||
$attrs = array(
|
$attrs = [
|
||||||
'argument_name' => (string) $key,
|
'argument_name' => (string) $key,
|
||||||
);
|
];
|
||||||
|
|
||||||
$map = array(
|
$map = [
|
||||||
'skip_key' => 'skip_key',
|
'skip_key' => 'skip_key',
|
||||||
'repeat_key' => 'repeat_key',
|
'repeat_key' => 'repeat_key',
|
||||||
'required' => 'required',
|
'required' => 'required',
|
||||||
// 'order' => 'sort_order',
|
// 'order' => 'sort_order',
|
||||||
'description' => 'description',
|
'description' => 'description',
|
||||||
'set_if' => 'set_if',
|
'set_if' => 'set_if',
|
||||||
);
|
];
|
||||||
|
|
||||||
$argValue = null;
|
$argValue = null;
|
||||||
if (is_object($value)) {
|
if (is_object($value)) {
|
||||||
@ -187,7 +189,7 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
{
|
{
|
||||||
if (empty($arguments)) {
|
if (empty($arguments)) {
|
||||||
if (count($this->arguments)) {
|
if (count($this->arguments)) {
|
||||||
$this->arguments = array();
|
$this->arguments = [];
|
||||||
$this->modified = true;
|
$this->modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +220,7 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
/**
|
/**
|
||||||
* Magic isset check
|
* Magic isset check
|
||||||
*
|
*
|
||||||
|
* @param string $argument
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function __isset($argument)
|
public function __isset($argument)
|
||||||
@ -244,13 +247,13 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
public function add(IcingaCommandArgument $argument)
|
public function add(IcingaCommandArgument $argument)
|
||||||
{
|
{
|
||||||
if (array_key_exists($argument->argument_name, $this->arguments)) {
|
$name = $argument->get('argument_name');
|
||||||
|
if (array_key_exists($name, $this->arguments)) {
|
||||||
// TODO: Fail unless $argument equals existing one
|
// TODO: Fail unless $argument equals existing one
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->arguments[$argument->argument_name] = $argument;
|
$this->arguments[$name] = $argument;
|
||||||
$connection = $this->object->getConnection();
|
|
||||||
$this->modified = true;
|
$this->modified = true;
|
||||||
$this->refreshIndex();
|
$this->refreshIndex();
|
||||||
|
|
||||||
@ -269,13 +272,13 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
$table = $this->object->getTableName();
|
$table = $this->object->getTableName();
|
||||||
$query = $db->select()->from(
|
$query = $db->select()->from(
|
||||||
array('o' => $table),
|
['o' => $table],
|
||||||
array()
|
[]
|
||||||
)->join(
|
)->join(
|
||||||
array('a' => 'icinga_command_argument'),
|
['a' => 'icinga_command_argument'],
|
||||||
'o.id = a.command_id',
|
'o.id = a.command_id',
|
||||||
'*'
|
'*'
|
||||||
)->where('o.object_name = ?', $this->object->object_name)
|
)->where('o.object_name = ?', $this->object->getObjectName())
|
||||||
->order('a.sort_order')->order('a.argument_name');
|
->order('a.sort_order')->order('a.argument_name');
|
||||||
|
|
||||||
$this->arguments = IcingaCommandArgument::loadAll($connection, $query, 'argument_name');
|
$this->arguments = IcingaCommandArgument::loadAll($connection, $query, 'argument_name');
|
||||||
@ -292,18 +295,18 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
$resolveIds = true
|
$resolveIds = true
|
||||||
) {
|
) {
|
||||||
if ($chosenProperties !== null) {
|
if ($chosenProperties !== null) {
|
||||||
throw new ProgrammingError(
|
throw new InvalidArgumentException(
|
||||||
'IcingaArguments does not support chosenProperties[]'
|
'IcingaArguments does not support chosenProperties[]'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = array();
|
$args = [];
|
||||||
foreach ($this->arguments as $arg) {
|
foreach ($this->arguments as $arg) {
|
||||||
if ($arg->shouldBeRemoved()) {
|
if ($arg->shouldBeRemoved()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$args[$arg->argument_name] = $arg->toPlainObject(
|
$args[$arg->get('argument_name')] = $arg->toPlainObject(
|
||||||
$resolved,
|
$resolved,
|
||||||
$skipDefaults,
|
$skipDefaults,
|
||||||
null,
|
null,
|
||||||
@ -316,7 +319,7 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
public function toUnmodifiedPlainObject()
|
public function toUnmodifiedPlainObject()
|
||||||
{
|
{
|
||||||
$args = array();
|
$args = [];
|
||||||
foreach ($this->storedArguments as $key => $arg) {
|
foreach ($this->storedArguments as $key => $arg) {
|
||||||
$args[$arg->argument_name] = $arg->toPlainObject();
|
$args[$arg->argument_name] = $arg->toPlainObject();
|
||||||
}
|
}
|
||||||
@ -326,7 +329,7 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
protected function cloneStored()
|
protected function cloneStored()
|
||||||
{
|
{
|
||||||
$this->storedArguments = array();
|
$this->storedArguments = [];
|
||||||
foreach ($this->arguments as $k => $v) {
|
foreach ($this->arguments as $k => $v) {
|
||||||
$this->storedArguments[$k] = clone($v);
|
$this->storedArguments[$k] = clone($v);
|
||||||
}
|
}
|
||||||
@ -338,18 +341,19 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
return $arguments->loadFromDb();
|
return $arguments->loadFromDb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $this
|
||||||
|
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||||
|
*/
|
||||||
public function store()
|
public function store()
|
||||||
{
|
{
|
||||||
$db = $this->object->getConnection();
|
$db = $this->object->getConnection();
|
||||||
|
$deleted = [];
|
||||||
$dummy = IcingaCommandArgument::create();
|
|
||||||
|
|
||||||
$deleted = array();
|
|
||||||
foreach ($this->arguments as $key => $argument) {
|
foreach ($this->arguments as $key => $argument) {
|
||||||
if ($argument->shouldBeRemoved()) {
|
if ($argument->shouldBeRemoved()) {
|
||||||
$deleted[] = $key;
|
$deleted[] = $key;
|
||||||
} else {
|
} else {
|
||||||
$argument->command_id = $this->object->id;
|
$argument->set('command_id', $this->object->get('id'));
|
||||||
$argument->store($db);
|
$argument->store($db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,6 +364,7 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->cloneStored();
|
$this->cloneStored();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,13 +374,13 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = array();
|
$args = [];
|
||||||
foreach ($this->arguments as $arg) {
|
foreach ($this->arguments as $arg) {
|
||||||
if ($arg->shouldBeRemoved()) {
|
if ($arg->shouldBeRemoved()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$args[$arg->argument_name] = $arg->toConfigString();
|
$args[$arg->get('argument_name')] = $arg->toConfigString();
|
||||||
}
|
}
|
||||||
return c::renderKeyOperatorValue('arguments', '+=', c::renderDictionary($args));
|
return c::renderKeyOperatorValue('arguments', '+=', c::renderDictionary($args));
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Objects;
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
use Icinga\Exception\ProgrammingError;
|
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
class IcingaCommandArgument extends IcingaObject
|
class IcingaCommandArgument extends IcingaObject
|
||||||
{
|
{
|
||||||
@ -52,7 +52,7 @@ class IcingaCommandArgument extends IcingaObject
|
|||||||
|
|
||||||
public function isSkippingKey()
|
public function isSkippingKey()
|
||||||
{
|
{
|
||||||
return $this->skip_key === 'y' || $this->argument_name === null;
|
return $this->get('skip_key') === 'y' || $this->get('argument_name') === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve is not supported
|
// Preserve is not supported
|
||||||
@ -159,13 +159,13 @@ class IcingaCommandArgument extends IcingaObject
|
|||||||
$resolveIds = true
|
$resolveIds = true
|
||||||
) {
|
) {
|
||||||
if ($resolved) {
|
if ($resolved) {
|
||||||
throw new ProgrammingError(
|
throw new RuntimeException(
|
||||||
'A single CommandArgument cannot be resolved'
|
'A single CommandArgument cannot be resolved'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($chosenProperties) {
|
if ($chosenProperties) {
|
||||||
throw new ProgrammingError(
|
throw new RuntimeException(
|
||||||
'IcingaCommandArgument does not support chosenProperties[]'
|
'IcingaCommandArgument does not support chosenProperties[]'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -181,64 +181,65 @@ class IcingaCommandArgument extends IcingaObject
|
|||||||
public function toConfigString()
|
public function toConfigString()
|
||||||
{
|
{
|
||||||
$data = array();
|
$data = array();
|
||||||
if ($this->argument_value) {
|
$value = $this->get('argument_value');
|
||||||
switch ($this->argument_format) {
|
if ($value) {
|
||||||
|
switch ($this->get('argument_format')) {
|
||||||
case 'string':
|
case 'string':
|
||||||
$data['value'] = c::renderString($this->argument_value);
|
$data['value'] = c::renderString($value);
|
||||||
break;
|
break;
|
||||||
case 'json':
|
case 'json':
|
||||||
if (is_object($this->argument_value)) {
|
if (is_object($value)) {
|
||||||
$data['value'] = c::renderDictionary($this->argument_value);
|
$data['value'] = c::renderDictionary($value);
|
||||||
} elseif (is_array($this->argument_value)) {
|
} elseif (is_array($value)) {
|
||||||
$data['value'] = c::renderArray($this->argument_value);
|
$data['value'] = c::renderArray($value);
|
||||||
} elseif (is_null($this->argument_value)) {
|
} elseif (is_null($value)) {
|
||||||
// TODO: recheck all this. I bet we never reach this:
|
// TODO: recheck all this. I bet we never reach this:
|
||||||
$data['value'] = 'null';
|
$data['value'] = 'null';
|
||||||
} elseif (is_bool($this->argument_value)) {
|
} elseif (is_bool($value)) {
|
||||||
$data['value'] = c::renderBoolean($this->argument_value);
|
$data['value'] = c::renderBoolean($value);
|
||||||
} else {
|
} else {
|
||||||
$data['value'] = $this->argument_value;
|
$data['value'] = $value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'expression':
|
case 'expression':
|
||||||
$data['value'] = c::renderExpression($this->argument_value);
|
$data['value'] = c::renderExpression($value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->sort_order !== null) {
|
if ($this->get('sort_order') !== null) {
|
||||||
$data['order'] = $this->sort_order;
|
$data['order'] = $this->get('sort_order');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->set_if) {
|
if (null !== $this->get('set_if')) {
|
||||||
switch ($this->set_if_format) {
|
switch ($this->get('set_if_format')) {
|
||||||
case 'expression':
|
case 'expression':
|
||||||
$data['set_if'] = c::renderExpression($this->set_if);
|
$data['set_if'] = c::renderExpression($this->get('set_if'));
|
||||||
break;
|
break;
|
||||||
case 'string':
|
case 'string':
|
||||||
default:
|
default:
|
||||||
$data['set_if'] = c::renderString($this->set_if);
|
$data['set_if'] = c::renderString($this->get('set_if'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->required) {
|
if (null !== $this->get('required')) {
|
||||||
$data['required'] = c::renderBoolean($this->required);
|
$data['required'] = c::renderBoolean($this->get('required'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isSkippingKey()) {
|
if ($this->isSkippingKey()) {
|
||||||
$data['skip_key'] = c::renderBoolean('y');
|
$data['skip_key'] = c::renderBoolean('y');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->repeat_key) {
|
if (null !== $this->get('repeat_key')) {
|
||||||
$data['repeat_key'] = c::renderBoolean($this->repeat_key);
|
$data['repeat_key'] = c::renderBoolean($this->get('repeat_key'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->description) {
|
if (null !== $this->get('description')) {
|
||||||
$data['description'] = c::renderString($this->description);
|
$data['description'] = c::renderString($this->get('description'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_keys($data) === array('value')) {
|
if (array_keys($data) === ['value']) {
|
||||||
return $data['value'];
|
return $data['value'];
|
||||||
} else {
|
} else {
|
||||||
return c::renderDictionary($data);
|
return c::renderDictionary($data);
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Objects;
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
use Icinga\Exception\ConfigurationError;
|
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
class IcingaNotification extends IcingaObject
|
class IcingaNotification extends IcingaObject
|
||||||
{
|
{
|
||||||
protected $table = 'icinga_notification';
|
protected $table = 'icinga_notification';
|
||||||
|
|
||||||
protected $defaultProperties = array(
|
protected $defaultProperties = [
|
||||||
'id' => null,
|
'id' => null,
|
||||||
'object_name' => null,
|
'object_name' => null,
|
||||||
'object_type' => null,
|
'object_type' => null,
|
||||||
@ -26,7 +26,7 @@ class IcingaNotification extends IcingaObject
|
|||||||
'period_id' => null,
|
'period_id' => null,
|
||||||
'zone_id' => null,
|
'zone_id' => null,
|
||||||
'assign_filter' => null,
|
'assign_filter' => null,
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $supportsCustomVars = true;
|
protected $supportsCustomVars = true;
|
||||||
|
|
||||||
@ -36,29 +36,29 @@ class IcingaNotification extends IcingaObject
|
|||||||
|
|
||||||
protected $supportsApplyRules = true;
|
protected $supportsApplyRules = true;
|
||||||
|
|
||||||
protected $relatedSets = array(
|
protected $relatedSets = [
|
||||||
'states' => 'StateFilterSet',
|
'states' => 'StateFilterSet',
|
||||||
'types' => 'TypeFilterSet',
|
'types' => 'TypeFilterSet',
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $multiRelations = array(
|
protected $multiRelations = [
|
||||||
'users' => 'IcingaUser',
|
'users' => 'IcingaUser',
|
||||||
'user_groups' => 'IcingaUserGroup',
|
'user_groups' => 'IcingaUserGroup',
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $relations = array(
|
protected $relations = [
|
||||||
'zone' => 'IcingaZone',
|
'zone' => 'IcingaZone',
|
||||||
'host' => 'IcingaHost',
|
'host' => 'IcingaHost',
|
||||||
'service' => 'IcingaService',
|
'service' => 'IcingaService',
|
||||||
'command' => 'IcingaCommand',
|
'command' => 'IcingaCommand',
|
||||||
'period' => 'IcingaTimePeriod',
|
'period' => 'IcingaTimePeriod',
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $intervalProperties = array(
|
protected $intervalProperties = [
|
||||||
'notification_interval' => 'interval',
|
'notification_interval' => 'interval',
|
||||||
'times_begin' => 'times_begin',
|
'times_begin' => 'times_begin',
|
||||||
'times_end' => 'times_end',
|
'times_end' => 'times_end',
|
||||||
);
|
];
|
||||||
|
|
||||||
protected function prefersGlobalZone()
|
protected function prefersGlobalZone()
|
||||||
{
|
{
|
||||||
@ -78,18 +78,15 @@ class IcingaNotification extends IcingaObject
|
|||||||
protected function renderTimes_begin()
|
protected function renderTimes_begin()
|
||||||
{
|
{
|
||||||
// @codingStandardsIgnoreEnd
|
// @codingStandardsIgnoreEnd
|
||||||
$times = (object) array(
|
$times = (object) [
|
||||||
'begin' => c::renderInterval($this->times_begin)
|
'begin' => c::renderInterval($this->times_begin)
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($this->times_end !== null) {
|
if ($this->get('times_end') !== null) {
|
||||||
$times->end = c::renderInterval($this->times_end);
|
$times->end = c::renderInterval($this->get('times_end'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return c::renderKeyValue(
|
return c::renderKeyValue('times', c::renderDictionary($times));
|
||||||
'times',
|
|
||||||
c::renderDictionary($times)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,18 +103,15 @@ class IcingaNotification extends IcingaObject
|
|||||||
{
|
{
|
||||||
// @codingStandardsIgnoreEnd
|
// @codingStandardsIgnoreEnd
|
||||||
|
|
||||||
if ($this->times_begin !== null) {
|
if ($this->get('times_begin') !== null) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$times = (object) array(
|
$times = (object) [
|
||||||
'end' => c::renderInterval($this->times_end)
|
'end' => c::renderInterval($this->get('times_end'))
|
||||||
);
|
];
|
||||||
|
|
||||||
return c::renderKeyValue(
|
return c::renderKeyValue('times', c::renderDictionary($times));
|
||||||
'times',
|
|
||||||
c::renderDictionary($times)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,10 +132,10 @@ class IcingaNotification extends IcingaObject
|
|||||||
{
|
{
|
||||||
if ($this->isApplyRule()) {
|
if ($this->isApplyRule()) {
|
||||||
if (($to = $this->get('apply_to')) === null) {
|
if (($to = $this->get('apply_to')) === null) {
|
||||||
throw new ConfigurationError(
|
throw new RuntimeException(sprintf(
|
||||||
'Applied notification "%s" has no valid object type',
|
'Applied notification "%s" has no valid object type',
|
||||||
$this->getObjectName()
|
$this->getObjectName()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
@ -161,7 +155,7 @@ class IcingaNotification extends IcingaObject
|
|||||||
if (is_int($key)) {
|
if (is_int($key)) {
|
||||||
$this->id = $key;
|
$this->id = $key;
|
||||||
} elseif (is_array($key)) {
|
} elseif (is_array($key)) {
|
||||||
foreach (array('id', 'host_id', 'service_id', 'object_name') as $k) {
|
foreach (['id', 'host_id', 'service_id', 'object_name'] as $k) {
|
||||||
if (array_key_exists($k, $key)) {
|
if (array_key_exists($k, $key)) {
|
||||||
$this->set($k, $key[$k]);
|
$this->set($k, $key[$k]);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use Exception;
|
|||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Data\Filter\FilterChain;
|
use Icinga\Data\Filter\FilterChain;
|
||||||
use Icinga\Data\Filter\FilterExpression;
|
use Icinga\Data\Filter\FilterExpression;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\NotFoundError;
|
||||||
use Icinga\Module\Director\CustomVariable\CustomVariables;
|
use Icinga\Module\Director\CustomVariable\CustomVariables;
|
||||||
use Icinga\Module\Director\IcingaConfig\AssignRenderer;
|
use Icinga\Module\Director\IcingaConfig\AssignRenderer;
|
||||||
use Icinga\Module\Director\Data\Db\DbObject;
|
use Icinga\Module\Director\Data\Db\DbObject;
|
||||||
@ -21,6 +21,7 @@ use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1;
|
|||||||
use Icinga\Module\Director\Repository\IcingaTemplateRepository;
|
use Icinga\Module\Director\Repository\IcingaTemplateRepository;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
||||||
{
|
{
|
||||||
@ -62,22 +63,22 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
protected $type;
|
protected $type;
|
||||||
|
|
||||||
/* key/value!! */
|
/* key/value!! */
|
||||||
protected $booleans = array();
|
protected $booleans = [];
|
||||||
|
|
||||||
// Property suffixed with _id must exist
|
// Property suffixed with _id must exist
|
||||||
protected $relations = array(
|
protected $relations = [
|
||||||
// property => PropertyClass
|
// property => PropertyClass
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $relatedSets = array(
|
protected $relatedSets = [
|
||||||
// property => ExtensibleSetClass
|
// property => ExtensibleSetClass
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $multiRelations = array(
|
protected $multiRelations = [
|
||||||
// property => IcingaObjectClass
|
// property => IcingaObjectClass
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $loadedMultiRelations = array();
|
protected $loadedMultiRelations = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to set properties pointing to related objects by name without
|
* Allows to set properties pointing to related objects by name without
|
||||||
@ -85,18 +86,18 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $unresolvedRelatedProperties = array();
|
protected $unresolvedRelatedProperties = [];
|
||||||
|
|
||||||
protected $loadedRelatedSets = array();
|
protected $loadedRelatedSets = [];
|
||||||
|
|
||||||
// Will be rendered first, before imports
|
// Will be rendered first, before imports
|
||||||
protected $prioritizedProperties = array();
|
protected $prioritizedProperties = [];
|
||||||
|
|
||||||
protected $propertiesNotForRendering = array(
|
protected $propertiesNotForRendering = [
|
||||||
'id',
|
'id',
|
||||||
'object_name',
|
'object_name',
|
||||||
'object_type',
|
'object_type',
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of interval property names
|
* Array of interval property names
|
||||||
@ -106,7 +107,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $intervalProperties = array();
|
protected $intervalProperties = [];
|
||||||
|
|
||||||
/** @var Db */
|
/** @var Db */
|
||||||
protected $connection;
|
protected $connection;
|
||||||
@ -123,7 +124,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
|
|
||||||
private $shouldBeRemoved = false;
|
private $shouldBeRemoved = false;
|
||||||
|
|
||||||
private $resolveCache = array();
|
private $resolveCache = [];
|
||||||
|
|
||||||
private $cachedPlainUnmodified;
|
private $cachedPlainUnmodified;
|
||||||
|
|
||||||
@ -294,23 +295,47 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $this->relations[$property];
|
return $this->relations[$property];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $property
|
||||||
|
* @return IcingaObject
|
||||||
|
*/
|
||||||
public function getRelated($property)
|
public function getRelated($property)
|
||||||
{
|
{
|
||||||
return $this->getRelatedObject($property, $this->{$property . '_id'});
|
return $this->getRelatedObject($property, $this->{$property . '_id'});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $property
|
||||||
|
* @param $id
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
protected function getRelatedObjectName($property, $id)
|
protected function getRelatedObjectName($property, $id)
|
||||||
{
|
{
|
||||||
return $this->getRelatedObject($property, $id)->object_name;
|
return $this->getRelatedObject($property, $id)->getObjectName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $property
|
||||||
|
* @param $id
|
||||||
|
* @return IcingaObject
|
||||||
|
*/
|
||||||
protected function getRelatedObject($property, $id)
|
protected function getRelatedObject($property, $id)
|
||||||
{
|
{
|
||||||
/** @var IcingaObject $class */
|
/** @var IcingaObject $class */
|
||||||
$class = $this->getRelationClass($property);
|
$class = $this->getRelationClass($property);
|
||||||
return $class::loadWithAutoIncId($id, $this->connection);
|
try {
|
||||||
|
$object = $class::loadWithAutoIncId($id, $this->connection);
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $property
|
||||||
|
* @return IcingaObject|null
|
||||||
|
*/
|
||||||
public function getResolvedRelated($property)
|
public function getResolvedRelated($property)
|
||||||
{
|
{
|
||||||
$id = $this->getSingleResolvedProperty($property . '_id');
|
$id = $this->getSingleResolvedProperty($property . '_id');
|
||||||
@ -336,7 +361,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
/** @var static $class */
|
/** @var static $class */
|
||||||
$class = self::classByType($type);
|
$class = self::classByType($type);
|
||||||
/** @var static $dummy */
|
/** @var static $dummy */
|
||||||
$dummy = $class::create(array(), $db);
|
$dummy = $class::create([], $db);
|
||||||
$dummy->prefetchAllRelatedTypes();
|
$dummy->prefetchAllRelatedTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,20 +521,30 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
*/
|
||||||
protected function resolveUnresolvedRelatedProperty($name)
|
protected function resolveUnresolvedRelatedProperty($name)
|
||||||
{
|
{
|
||||||
$short = substr($name, 0, -3);
|
$short = substr($name, 0, -3);
|
||||||
/** @var IcingaObject $class */
|
/** @var IcingaObject $class */
|
||||||
$class = $this->getRelationClass($short);
|
$class = $this->getRelationClass($short);
|
||||||
$object = $class::load(
|
try {
|
||||||
$this->unresolvedRelatedProperties[$name],
|
$object = $class::load(
|
||||||
$this->connection
|
$this->unresolvedRelatedProperties[$name],
|
||||||
);
|
$this->connection
|
||||||
|
);
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
|
||||||
$this->reallySet($name, $object->get('id'));
|
$this->reallySet($name, $object->get('id'));
|
||||||
unset($this->unresolvedRelatedProperties[$name]);
|
unset($this->unresolvedRelatedProperties[$name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function hasBeenModified()
|
public function hasBeenModified()
|
||||||
{
|
{
|
||||||
if (parent::hasBeenModified()) {
|
if (parent::hasBeenModified()) {
|
||||||
@ -573,6 +608,10 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return array_key_exists($name, $this->unresolvedRelatedProperties);
|
return array_key_exists($name, $this->unresolvedRelatedProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
protected function getRelationId($key)
|
protected function getRelationId($key)
|
||||||
{
|
{
|
||||||
if ($this->hasUnresolvedRelatedProperty($key)) {
|
if ($this->hasUnresolvedRelatedProperty($key)) {
|
||||||
@ -582,6 +621,10 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return parent::get($key);
|
return parent::get($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
protected function getRelatedProperty($key)
|
protected function getRelatedProperty($key)
|
||||||
{
|
{
|
||||||
$idKey = $key . '_id';
|
$idKey = $key . '_id';
|
||||||
@ -592,13 +635,22 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
if ($id = $this->get($idKey)) {
|
if ($id = $this->get($idKey)) {
|
||||||
/** @var IcingaObject $class */
|
/** @var IcingaObject $class */
|
||||||
$class = $this->getRelationClass($key);
|
$class = $this->getRelationClass($key);
|
||||||
$object = $class::loadWithAutoIncId($id, $this->connection);
|
try {
|
||||||
return $object->get('object_name');
|
$object = $class::loadWithAutoIncId($id, $this->connection);
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
throw new RuntimeException($e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $object->getObjectName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return \Icinga\Module\Director\CustomVariable\CustomVariable|mixed|null
|
||||||
|
*/
|
||||||
public function get($key)
|
public function get($key)
|
||||||
{
|
{
|
||||||
if (substr($key, 0, 5) === 'vars.') {
|
if (substr($key, 0, 5) === 'vars.') {
|
||||||
@ -1026,6 +1078,10 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $this->groups()->listGroupNames();
|
return $this->groups()->listGroupNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
public function listInheritedGroupNames()
|
public function listInheritedGroupNames()
|
||||||
{
|
{
|
||||||
$parents = $this->imports()->getObjects();
|
$parents = $this->imports()->getObjects();
|
||||||
@ -1046,6 +1102,10 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
public function listResolvedGroupNames()
|
public function listResolvedGroupNames()
|
||||||
{
|
{
|
||||||
$groups = $this->groups()->listGroupNames();
|
$groups = $this->groups()->listGroupNames();
|
||||||
@ -1056,6 +1116,11 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $groups;
|
return $groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $group
|
||||||
|
* @return bool
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
public function hasGroup($group)
|
public function hasGroup($group)
|
||||||
{
|
{
|
||||||
if ($group instanceof static) {
|
if ($group instanceof static) {
|
||||||
@ -1139,8 +1204,14 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var IcingaObject $object */
|
/** @var IcingaObject[] $imports */
|
||||||
foreach (array_reverse($this->imports()->getObjects()) as $object) {
|
try {
|
||||||
|
$imports = array_reverse($this->imports()->getObjects());
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
throw new RuntimeException($e->getMessage(), 0, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($imports as $object) {
|
||||||
$v = $object->getSingleResolvedProperty($key);
|
$v = $object->getSingleResolvedProperty($key);
|
||||||
if (null !== $v) {
|
if (null !== $v) {
|
||||||
return $v;
|
return $v;
|
||||||
@ -1368,6 +1439,11 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
&& $this->get('object_type') === 'apply';
|
&& $this->get('object_type') === 'apply';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NotFoundError
|
||||||
|
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||||
|
* @throws \Zend_Db_Adapter_Exception
|
||||||
|
*/
|
||||||
protected function storeRelatedObjects()
|
protected function storeRelatedObjects()
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
@ -1380,6 +1456,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
->storeArguments();
|
->storeArguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
protected function beforeStore()
|
protected function beforeStore()
|
||||||
{
|
{
|
||||||
$this->resolveUnresolvedRelatedProperties();
|
$this->resolveUnresolvedRelatedProperties();
|
||||||
@ -1388,12 +1467,22 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NotFoundError
|
||||||
|
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||||
|
* @throws \Zend_Db_Adapter_Exception
|
||||||
|
*/
|
||||||
public function onInsert()
|
public function onInsert()
|
||||||
{
|
{
|
||||||
DirectorActivityLog::logCreation($this, $this->connection);
|
DirectorActivityLog::logCreation($this, $this->connection);
|
||||||
$this->storeRelatedObjects();
|
$this->storeRelatedObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NotFoundError
|
||||||
|
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||||
|
* @throws \Zend_Db_Adapter_Exception
|
||||||
|
*/
|
||||||
public function onUpdate()
|
public function onUpdate()
|
||||||
{
|
{
|
||||||
DirectorActivityLog::logModification($this, $this->connection);
|
DirectorActivityLog::logModification($this, $this->connection);
|
||||||
@ -1454,7 +1543,8 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return self
|
* @return $this
|
||||||
|
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||||
*/
|
*/
|
||||||
protected function storeArguments()
|
protected function storeArguments()
|
||||||
{
|
{
|
||||||
@ -1470,7 +1560,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return self
|
* @return $this
|
||||||
*/
|
*/
|
||||||
protected function storeRelatedSets()
|
protected function storeRelatedSets()
|
||||||
{
|
{
|
||||||
@ -1484,7 +1574,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return self
|
* @return $this
|
||||||
|
* @throws NotFoundError
|
||||||
|
* @throws \Zend_Db_Adapter_Exception
|
||||||
*/
|
*/
|
||||||
protected function storeImports()
|
protected function storeImports()
|
||||||
{
|
{
|
||||||
@ -1571,7 +1663,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
&& array_key_exists('enable_active_checks', $this->defaultProperties)
|
&& array_key_exists('enable_active_checks', $this->defaultProperties)
|
||||||
) {
|
) {
|
||||||
$passive = clone($this);
|
$passive = clone($this);
|
||||||
$passive->enable_active_checks = false;
|
$passive->set('enable_active_checks', false);
|
||||||
|
|
||||||
$config->configFile(
|
$config->configFile(
|
||||||
'director/master/' . $filename,
|
'director/master/' . $filename,
|
||||||
@ -1624,6 +1716,12 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $filename;
|
return $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $zoneId
|
||||||
|
* @param IcingaConfig|null $config
|
||||||
|
* @return string
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
protected function getNameForZoneId($zoneId, IcingaConfig $config = null)
|
protected function getNameForZoneId($zoneId, IcingaConfig $config = null)
|
||||||
{
|
{
|
||||||
// TODO: this is still ugly.
|
// TODO: this is still ugly.
|
||||||
@ -1645,13 +1743,13 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->hasProperty('zone_id')) {
|
if ($this->hasProperty('zone_id')) {
|
||||||
if (! $this->supportsImports()) {
|
|
||||||
if ($zoneId = $this->get('zone_id')) {
|
|
||||||
return $this->getNameForZoneId($zoneId, $config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (! $this->supportsImports()) {
|
||||||
|
if ($zoneId = $this->get('zone_id')) {
|
||||||
|
return $this->getNameForZoneId($zoneId, $config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($zoneId = $this->getSingleResolvedProperty('zone_id')) {
|
if ($zoneId = $this->getSingleResolvedProperty('zone_id')) {
|
||||||
return $this->getNameForZoneId($zoneId, $config);
|
return $this->getNameForZoneId($zoneId, $config);
|
||||||
}
|
}
|
||||||
@ -1802,7 +1900,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
{
|
{
|
||||||
return c1::renderKeyValue(
|
return c1::renderKeyValue(
|
||||||
$legacyKey,
|
$legacyKey,
|
||||||
c1::renderBoolean($this->$property)
|
c1::renderBoolean($this->get($property))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1956,12 +2054,12 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
|
|
||||||
protected function renderBooleanProperty($key)
|
protected function renderBooleanProperty($key)
|
||||||
{
|
{
|
||||||
return c::renderKeyValue($key, c::renderBoolean($this->$key));
|
return c::renderKeyValue($key, c::renderBoolean($this->get($key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderPropertyAsSeconds($key)
|
protected function renderPropertyAsSeconds($key)
|
||||||
{
|
{
|
||||||
return c::renderKeyValue($key, c::renderInterval($this->$key));
|
return c::renderKeyValue($key, c::renderInterval($this->get($key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderSuffix()
|
protected function renderSuffix()
|
||||||
@ -2406,6 +2504,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
* @param Db $db
|
* @param Db $db
|
||||||
*
|
*
|
||||||
* @return IcingaObject
|
* @return IcingaObject
|
||||||
|
* @throws NotFoundError
|
||||||
*/
|
*/
|
||||||
public static function loadByType($type, $id, Db $db)
|
public static function loadByType($type, $id, Db $db)
|
||||||
{
|
{
|
||||||
@ -2499,6 +2598,12 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return static::create((array) $plain, $connection);
|
return static::create((array) $plain, $connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IcingaObject $object
|
||||||
|
* @param null $preserve
|
||||||
|
* @return $this
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
public function replaceWith(IcingaObject $object, $preserve = null)
|
public function replaceWith(IcingaObject $object, $preserve = null)
|
||||||
{
|
{
|
||||||
if ($preserve === null) {
|
if ($preserve === null) {
|
||||||
@ -2517,7 +2622,14 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: with rules? What if I want to override vars? Drop in favour of vars.x?
|
/**
|
||||||
|
* TODO: with rules? What if I want to override vars? Drop in favour of vars.x?
|
||||||
|
*
|
||||||
|
* @param IcingaObject $object
|
||||||
|
* @param bool $replaceVars
|
||||||
|
* @return $this
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
public function merge(IcingaObject $object, $replaceVars = false)
|
public function merge(IcingaObject $object, $replaceVars = false)
|
||||||
{
|
{
|
||||||
$object = clone($object);
|
$object = clone($object);
|
||||||
@ -2577,6 +2689,14 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $resolved
|
||||||
|
* @param bool $skipDefaults
|
||||||
|
* @param array|null $chosenProperties
|
||||||
|
* @param bool $resolveIds
|
||||||
|
* @return object
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
public function toPlainObject(
|
public function toPlainObject(
|
||||||
$resolved = false,
|
$resolved = false,
|
||||||
$skipDefaults = false,
|
$skipDefaults = false,
|
||||||
@ -2813,6 +2933,13 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
return 'director/' . $plural;
|
return 'director/' . $plural;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $resolved
|
||||||
|
* @param bool $skipDefaults
|
||||||
|
* @param array|null $chosenProperties
|
||||||
|
* @return string
|
||||||
|
* @throws NotFoundError
|
||||||
|
*/
|
||||||
public function toJson(
|
public function toJson(
|
||||||
$resolved = false,
|
$resolved = false,
|
||||||
$skipDefaults = false,
|
$skipDefaults = false,
|
||||||
|
@ -4,22 +4,22 @@ namespace Icinga\Module\Director\Objects;
|
|||||||
|
|
||||||
use Countable;
|
use Countable;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Icinga\Exception\ProgrammingError;
|
|
||||||
use Iterator;
|
use Iterator;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1;
|
use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1;
|
||||||
use Icinga\Module\Director\Repository\IcingaTemplateRepository;
|
use Icinga\Module\Director\Repository\IcingaTemplateRepository;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
||||||
{
|
{
|
||||||
protected $storedNames = array();
|
protected $storedNames = [];
|
||||||
|
|
||||||
/** @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();
|
protected $imports = [];
|
||||||
|
|
||||||
/** @var IcingaObject[] A list of all objects we have seen, referred by name */
|
/** @var IcingaObject[] A list of all objects we have seen, referred by name */
|
||||||
protected $objects = array();
|
protected $objects = [];
|
||||||
|
|
||||||
protected $modified = false;
|
protected $modified = false;
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
private $position = 0;
|
private $position = 0;
|
||||||
|
|
||||||
protected $idx = array();
|
protected $idx = [];
|
||||||
|
|
||||||
public function __construct(IcingaObject $object)
|
public function __construct(IcingaObject $object)
|
||||||
{
|
{
|
||||||
@ -56,6 +56,10 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
return $this->modified;
|
return $this->modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IcingaObject|null
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
*/
|
||||||
public function current()
|
public function current()
|
||||||
{
|
{
|
||||||
if (! $this->valid()) {
|
if (! $this->valid()) {
|
||||||
@ -82,6 +86,11 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
return array_key_exists($this->position, $this->idx);
|
return array_key_exists($this->position, $this->idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @return IcingaObject|null
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
*/
|
||||||
public function get($key)
|
public function get($key)
|
||||||
{
|
{
|
||||||
if (array_key_exists($key, $this->imports)) {
|
if (array_key_exists($key, $this->imports)) {
|
||||||
@ -102,7 +111,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! is_array($import)) {
|
if (! is_array($import)) {
|
||||||
$import = array($import);
|
$import = [$import];
|
||||||
}
|
}
|
||||||
|
|
||||||
$existing = $this->listImportNames();
|
$existing = $this->listImportNames();
|
||||||
@ -112,13 +121,13 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->imports = array();
|
$this->imports = [];
|
||||||
return $this->add($import);
|
return $this->add($import);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function listNamesForGivenImports($imports)
|
protected function listNamesForGivenImports($imports)
|
||||||
{
|
{
|
||||||
$list = array();
|
$list = [];
|
||||||
$class = $this->getImportClass();
|
$class = $this->getImportClass();
|
||||||
|
|
||||||
foreach ($imports as $i) {
|
foreach ($imports as $i) {
|
||||||
@ -146,11 +155,11 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
public function clear()
|
public function clear()
|
||||||
{
|
{
|
||||||
if ($this->imports === array()) {
|
if ($this->imports === []) {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->imports = array();
|
$this->imports = [];
|
||||||
$this->modified = true;
|
$this->modified = true;
|
||||||
|
|
||||||
return $this->refreshIndex();
|
return $this->refreshIndex();
|
||||||
@ -171,6 +180,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
{
|
{
|
||||||
$this->idx = array_keys($this->imports);
|
$this->idx = array_keys($this->imports);
|
||||||
// $this->object->templateResolver()->refreshObject($this->object);
|
// $this->object->templateResolver()->refreshObject($this->object);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +197,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
$this->add($i);
|
$this->add($i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,10 +225,11 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return IcingaObject[]
|
* @return IcingaObject[]
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
*/
|
*/
|
||||||
public function getObjects()
|
public function getObjects()
|
||||||
{
|
{
|
||||||
$list = array();
|
$list = [];
|
||||||
foreach ($this->listImportNames() as $name) {
|
foreach ($this->listImportNames() as $name) {
|
||||||
$list[$name] = $this->getObject($name);
|
$list[$name] = $this->getObject($name);
|
||||||
}
|
}
|
||||||
@ -225,6 +237,11 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
* @return IcingaObject
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
*/
|
||||||
protected function getObject($name)
|
protected function getObject($name)
|
||||||
{
|
{
|
||||||
if (array_key_exists($name, $this->objects)) {
|
if (array_key_exists($name, $this->objects)) {
|
||||||
@ -236,13 +253,10 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
$class = $this->getImportClass();
|
$class = $this->getImportClass();
|
||||||
if (is_array($this->object->getKeyName())) {
|
if (is_array($this->object->getKeyName())) {
|
||||||
// Services only
|
// Services only
|
||||||
$import = $class::load(
|
$import = $class::load([
|
||||||
array(
|
'object_name' => $name,
|
||||||
'object_name' => $name,
|
'object_type' => 'template'
|
||||||
'object_type' => 'template'
|
], $connection);
|
||||||
),
|
|
||||||
$connection
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
$import = $class::load($name, $connection);
|
$import = $class::load($name, $connection);
|
||||||
}
|
}
|
||||||
@ -277,7 +291,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
$this->objects = IcingaTemplateRepository::instanceByObject($this->object)
|
$this->objects = IcingaTemplateRepository::instanceByObject($this->object)
|
||||||
->getTemplatesIndexedByNameFor($this->object);
|
->getTemplatesIndexedByNameFor($this->object);
|
||||||
if (empty($this->objects)) {
|
if (empty($this->objects)) {
|
||||||
$this->imports = array();
|
$this->imports = [];
|
||||||
} else {
|
} else {
|
||||||
$keys = array_keys($this->objects);
|
$keys = array_keys($this->objects);
|
||||||
$this->imports = array_combine($keys, $keys);
|
$this->imports = array_combine($keys, $keys);
|
||||||
@ -287,6 +301,11 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
* @throws \Zend_Db_Adapter_Exception
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
*/
|
||||||
public function store()
|
public function store()
|
||||||
{
|
{
|
||||||
if (! $this->hasBeenModified()) {
|
if (! $this->hasBeenModified()) {
|
||||||
@ -295,7 +314,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
$objectId = $this->object->get('id');
|
$objectId = $this->object->get('id');
|
||||||
if ($objectId === null) {
|
if ($objectId === null) {
|
||||||
throw new ProgrammingError(
|
throw new RuntimeException(
|
||||||
'Cannot store imports for unstored object with no ID'
|
'Cannot store imports for unstored object with no ID'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -318,14 +337,11 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||||||
|
|
||||||
$weight = 1;
|
$weight = 1;
|
||||||
foreach ($this->getObjects() as $import) {
|
foreach ($this->getObjects() as $import) {
|
||||||
$db->insert(
|
$db->insert($table, [
|
||||||
$table,
|
$objectCol => $objectId,
|
||||||
array(
|
$importCol => $import->get('id'),
|
||||||
$objectCol => $objectId,
|
'weight' => $weight++
|
||||||
$importCol => $import->get('id'),
|
]);
|
||||||
'weight' => $weight++
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->cloneStored();
|
$this->cloneStored();
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
namespace Icinga\Module\Director\Repository;
|
namespace Icinga\Module\Director\Repository;
|
||||||
|
|
||||||
use Icinga\Authentication\Auth;
|
use Icinga\Authentication\Auth;
|
||||||
use Icinga\Exception\ProgrammingError;
|
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Objects\IcingaObject;
|
use Icinga\Module\Director\Objects\IcingaObject;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
trait RepositoryByObjectHelper
|
trait RepositoryByObjectHelper
|
||||||
{
|
{
|
||||||
@ -62,7 +62,6 @@ trait RepositoryByObjectHelper
|
|||||||
* @param IcingaObject $object
|
* @param IcingaObject $object
|
||||||
* @param Db|null $connection
|
* @param Db|null $connection
|
||||||
* @return static
|
* @return static
|
||||||
* @throws ProgrammingError
|
|
||||||
*/
|
*/
|
||||||
public static function instanceByObject(IcingaObject $object, Db $connection = null)
|
public static function instanceByObject(IcingaObject $object, Db $connection = null)
|
||||||
{
|
{
|
||||||
@ -71,11 +70,11 @@ trait RepositoryByObjectHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! $connection) {
|
if (! $connection) {
|
||||||
throw new ProgrammingError(
|
throw new RuntimeException(sprintf(
|
||||||
'Cannot use repository for %s "%s" as it has no DB connection',
|
'Cannot use repository for %s "%s" as it has no DB connection',
|
||||||
$object->getShortTableName(),
|
$object->getShortTableName(),
|
||||||
$object->getObjectName()
|
$object->getObjectName()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::instanceByType(
|
return static::instanceByType(
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
namespace Icinga\Module\Director\Resolver;
|
namespace Icinga\Module\Director\Resolver;
|
||||||
|
|
||||||
use Icinga\Application\Benchmark;
|
use Icinga\Application\Benchmark;
|
||||||
use Icinga\Exception\ConfigurationError;
|
|
||||||
use Icinga\Exception\NotImplementedError;
|
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Objects\IcingaObject;
|
use Icinga\Module\Director\Objects\IcingaObject;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
class TemplateTree
|
class TemplateTree
|
||||||
{
|
{
|
||||||
@ -59,12 +58,12 @@ class TemplateTree
|
|||||||
if (array_key_exists($pid, $this->names)) {
|
if (array_key_exists($pid, $this->names)) {
|
||||||
$parents[] = $this->names[$pid];
|
$parents[] = $this->names[$pid];
|
||||||
} else {
|
} else {
|
||||||
throw new ConfigurationError(
|
throw new RuntimeException(sprintf(
|
||||||
'Got invalid parent id %d for %s "%s"',
|
'Got invalid parent id %d for %s "%s"',
|
||||||
$pid,
|
$pid,
|
||||||
$this->type,
|
$this->type,
|
||||||
$object->getObjectName()
|
$object->getObjectName()
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +124,9 @@ class TemplateTree
|
|||||||
if ($object->hasBeenLoadedFromDb()) {
|
if ($object->hasBeenLoadedFromDb()) {
|
||||||
return $this->getParentsById($object->getProperty('id'));
|
return $this->getParentsById($object->getProperty('id'));
|
||||||
} else {
|
} else {
|
||||||
throw new NotImplementedError('Not yet');
|
throw new RuntimeException(
|
||||||
|
'Loading parents for unstored objects has not been implemented yet'
|
||||||
|
);
|
||||||
// return $this->getParentsForUnstoredObject($object);
|
// return $this->getParentsForUnstoredObject($object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,7 +218,9 @@ class TemplateTree
|
|||||||
if ($object->hasBeenLoadedFromDb()) {
|
if ($object->hasBeenLoadedFromDb()) {
|
||||||
return $this->getChildrenById($object->getProperty('id'));
|
return $this->getChildrenById($object->getProperty('id'));
|
||||||
} else {
|
} else {
|
||||||
throw new NotImplementedError('Not yet');
|
throw new RuntimeException(
|
||||||
|
'Loading children for unstored objects has not been implemented yet'
|
||||||
|
);
|
||||||
// return $this->getChildrenForUnstoredObject($object);
|
// return $this->getChildrenForUnstoredObject($object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +241,9 @@ class TemplateTree
|
|||||||
if ($object->hasBeenLoadedFromDb()) {
|
if ($object->hasBeenLoadedFromDb()) {
|
||||||
return $this->getDescendantsById($object->getProperty('id'));
|
return $this->getDescendantsById($object->getProperty('id'));
|
||||||
} else {
|
} else {
|
||||||
throw new NotImplementedError('Not yet');
|
throw new RuntimeException(
|
||||||
|
'Loading descendants for unstored objects has not been implemented yet'
|
||||||
|
);
|
||||||
// return $this->getDescendantsForUnstoredObject($object);
|
// return $this->getDescendantsForUnstoredObject($object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,7 +267,10 @@ class TemplateTree
|
|||||||
if ($parentId === null) {
|
if ($parentId === null) {
|
||||||
return $this->returnFullTree();
|
return $this->returnFullTree();
|
||||||
} else {
|
} else {
|
||||||
return $this->partialTree($parentId);
|
throw new RuntimeException(
|
||||||
|
'Partial tree fetching has not been implemented yet'
|
||||||
|
);
|
||||||
|
// return $this->partialTree($parentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ trait FormElementContainer
|
|||||||
{
|
{
|
||||||
if (! array_key_exists($name, $this->elements)) {
|
if (! array_key_exists($name, $this->elements)) {
|
||||||
throw new InvalidArgumentException(sprintf(
|
throw new InvalidArgumentException(sprintf(
|
||||||
'Trying to get inexistant element "%s"',
|
'Trying to get non existent element "%s"',
|
||||||
$name
|
$name
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -60,10 +60,8 @@ trait FormElementContainer
|
|||||||
|
|
||||||
if ($this instanceof BaseHtmlElement) {
|
if ($this instanceof BaseHtmlElement) {
|
||||||
$element = $this->decorate($this->getElement($name));
|
$element = $this->decorate($this->getElement($name));
|
||||||
|
$this->add($element);
|
||||||
}
|
}
|
||||||
//...
|
|
||||||
|
|
||||||
$this->add($element);
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -103,7 +101,7 @@ trait FormElementContainer
|
|||||||
*
|
*
|
||||||
* @param $name
|
* @param $name
|
||||||
* @param $type
|
* @param $type
|
||||||
* @param $options
|
* @param $attributes
|
||||||
* @return BaseFormElement
|
* @return BaseFormElement
|
||||||
*/
|
*/
|
||||||
public function createElement($name, $type, $attributes = null)
|
public function createElement($name, $type, $attributes = null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user