Merge branch 'feature/branches-rewrite'
This commit is contained in:
commit
2906dc8acc
|
@ -5,18 +5,15 @@ namespace Icinga\Module\Director\Controllers;
|
|||
use gipfl\Diff\HtmlRenderer\SideBySideDiff;
|
||||
use gipfl\Diff\PhpDiff;
|
||||
use gipfl\IcingaWeb2\Widget\NameValueTable;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Data\Json;
|
||||
use Icinga\Module\Director\Db\Branch\IcingaObjectModification;
|
||||
use Icinga\Module\Director\Db\Branch\ObjectModification;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
|
||||
use Icinga\Module\Director\Db\Branch\BranchActivity;
|
||||
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use Icinga\Module\Director\PlainObjectRenderer;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
use Icinga\Module\Director\Web\Controller\BranchHelper;
|
||||
use Icinga\Module\Director\Web\Widget\IcingaConfigDiff;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\ValidHtml;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class BranchController extends ActionController
|
||||
{
|
||||
|
@ -29,66 +26,75 @@ class BranchController extends ActionController
|
|||
public function activityAction()
|
||||
{
|
||||
$this->assertPermission('director/showconfig');
|
||||
$uuid = Uuid::fromString($this->params->getRequired('uuid'));
|
||||
$ts = $this->params->getRequired('ts');
|
||||
$this->addSingleTab($this->translate('Activity'));
|
||||
$this->addTitle($this->translate('Branch Activity'));
|
||||
$activity = $this->loadBranchActivity($uuid);
|
||||
$activity = BranchActivity::load($ts, $this->db());
|
||||
$this->content()->add($this->prepareActivityInfo($activity));
|
||||
$this->showActivity($activity);
|
||||
}
|
||||
|
||||
protected function prepareActivityInfo($activity)
|
||||
protected function prepareActivityInfo(BranchActivity $activity)
|
||||
{
|
||||
$modification = ObjectModification::fromSerialization(json_decode($activity->change_set));
|
||||
/** @var IcingaObject $class IDE hint, it's a string */
|
||||
$class = $modification->getClassName();
|
||||
$keyParams = (array) $modification->getKeyParams(); // TODO: verify type
|
||||
$dummy = $class::create($keyParams);
|
||||
|
||||
$table = new NameValueTable();
|
||||
$table->addNameValuePairs([
|
||||
$this->translate('Author') => 'branch owner',
|
||||
$this->translate('Date') => date('Y-m-d H:i:s', $activity->change_time / 1000),
|
||||
$this->translate('Action') => $modification->getAction()
|
||||
. ' ' . $dummy->getShortTableName()
|
||||
. ' ' . $dummy->getObjectName(),
|
||||
$this->translate('Change UUID') => Uuid::fromBytes($activity->uuid)->toString(),
|
||||
$this->translate('Author') => $activity->getAuthor(),
|
||||
$this->translate('Date') => date('Y-m-d H:i:s', $activity->getTimestamp()),
|
||||
$this->translate('Action') => $activity->getAction()
|
||||
. ' ' . preg_replace('/^icinga_/', '', $activity->getObjectTable())
|
||||
. ' ' . $activity->getObjectName(),
|
||||
// $this->translate('Actions') => ['Undo form'],
|
||||
]);
|
||||
return $table;
|
||||
}
|
||||
|
||||
protected function showActivity($activity)
|
||||
protected function leftFromActivity(BranchActivity $activity)
|
||||
{
|
||||
$modification = ObjectModification::fromSerialization(Json::decode($activity->change_set));
|
||||
/** @var string|DbObject $class */
|
||||
$class = $modification->getClassName();
|
||||
|
||||
// TODO: Show JSON-Diff for non-IcingaObject's
|
||||
$keyParams = (array) $modification->getKeyParams(); // TODO: verify type
|
||||
$dummy = $class::create($keyParams, $this->db());
|
||||
if ($modification->isCreation()) {
|
||||
$left = $this->createEmptyConfig();
|
||||
$right = $dummy->setProperties(
|
||||
(array) $modification->getProperties()->jsonSerialize()
|
||||
)->toSingleIcingaConfig();
|
||||
} elseif ($modification->isDeletion()) {
|
||||
$left = $class::load($keyParams, $this->db())->toSingleIcingaConfig();
|
||||
$right = $this->createEmptyConfig();
|
||||
} else {
|
||||
// TODO: highlight properties that have been changed in the meantime
|
||||
// TODO: Deal with missing $existing
|
||||
$existing = $class::load($keyParams, $this->db());
|
||||
$left = $existing->toSingleIcingaConfig();
|
||||
$right = clone($existing);
|
||||
IcingaObjectModification::applyModification($modification, $right, $this->db());
|
||||
$right = $right->toSingleIcingaConfig();
|
||||
if ($activity->isActionCreate()) {
|
||||
return null;
|
||||
}
|
||||
$changes = $this->getConfigDiffs($left, $right);
|
||||
foreach ($changes as $filename => $diff) {
|
||||
$object = DbObjectTypeRegistry::newObject($activity->getObjectTable(), [], $this->db());
|
||||
foreach ($activity->getFormerProperties()->jsonSerialize() as $key => $value) {
|
||||
$object->set($key, $value);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
protected function rightFromActivity(BranchActivity $activity)
|
||||
{
|
||||
if ($activity->isActionDelete()) {
|
||||
return null;
|
||||
}
|
||||
$object = DbObjectTypeRegistry::newObject($activity->getObjectTable(), [], $this->db());
|
||||
if (! $activity->isActionCreate()) {
|
||||
foreach ($activity->getFormerProperties()->jsonSerialize() as $key => $value) {
|
||||
$object->set($key, $value);
|
||||
}
|
||||
}
|
||||
foreach ($activity->getModifiedProperties()->jsonSerialize() as $key => $value) {
|
||||
$object->set($key, $value);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
protected function showActivity(BranchActivity $activity)
|
||||
{
|
||||
$left = $this->leftFromActivity($activity);
|
||||
$right = $this->rightFromActivity($activity);
|
||||
if ($left instanceof IcingaObject || $right instanceof IcingaObject) {
|
||||
$this->content()->add(new IcingaConfigDiff(
|
||||
$left ? $left->toSingleIcingaConfig() : $this->createEmptyConfig(),
|
||||
$right ? $right->toSingleIcingaConfig() : $this->createEmptyConfig()
|
||||
));
|
||||
} else {
|
||||
$this->content()->add([
|
||||
Html::tag('h3', $filename),
|
||||
$diff
|
||||
Html::tag('h3', $this->translate('Modification')),
|
||||
new SideBySideDiff(new PhpDiff(
|
||||
PlainObjectRenderer::render($left->getProperties()),
|
||||
PlainObjectRenderer::render($right->getProperties())
|
||||
))
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -97,47 +103,4 @@ class BranchController extends ActionController
|
|||
{
|
||||
return new IcingaConfig($this->db());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IcingaConfig $oldConfig
|
||||
* @param IcingaConfig $newConfig
|
||||
* @return ValidHtml[]
|
||||
*/
|
||||
protected function getConfigDiffs(IcingaConfig $oldConfig, IcingaConfig $newConfig)
|
||||
{
|
||||
$oldFileNames = $oldConfig->getFileNames();
|
||||
$newFileNames = $newConfig->getFileNames();
|
||||
|
||||
$fileNames = array_merge($oldFileNames, $newFileNames);
|
||||
|
||||
$diffs = [];
|
||||
foreach ($fileNames as $filename) {
|
||||
if (in_array($filename, $oldFileNames)) {
|
||||
$left = $oldConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$left = '';
|
||||
}
|
||||
|
||||
if (in_array($filename, $newFileNames)) {
|
||||
$right = $newConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$right = '';
|
||||
}
|
||||
if ($left === $right) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$diffs[$filename] = new SideBySideDiff(new PhpDiff($left, $right));
|
||||
}
|
||||
|
||||
return $diffs;
|
||||
}
|
||||
|
||||
protected function loadBranchActivity(UuidInterface $uuid)
|
||||
{
|
||||
$db = $this->db()->getDbAdapter();
|
||||
return $db->fetchRow(
|
||||
$db->select()->from('director_branch_activity')->where('uuid = ?', $uuid->getBytes())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Module\Director\Objects\IcingaCommandArgument;
|
||||
use Icinga\Module\Director\Web\Table\BranchedIcingaCommandArgumentTable;
|
||||
use ipl\Html\Html;
|
||||
use Icinga\Module\Director\Forms\IcingaCommandArgumentForm;
|
||||
use Icinga\Module\Director\Objects\IcingaCommand;
|
||||
|
@ -22,9 +24,14 @@ class CommandController extends ObjectController
|
|||
parent::init();
|
||||
$o = $this->object;
|
||||
if ($o && ! $o->isExternal()) {
|
||||
if ($this->getBranch()->isBranch()) {
|
||||
$urlParams = ['uuid' => $o->getUniqueId()->toString()];
|
||||
} else {
|
||||
$urlParams = ['name' => $o->getObjectName()];
|
||||
}
|
||||
$this->tabs()->add('arguments', [
|
||||
'url' => 'director/command/arguments',
|
||||
'urlParams' => ['name' => $o->getObjectName()],
|
||||
'urlParams' => $urlParams,
|
||||
'label' => 'Arguments'
|
||||
]);
|
||||
}
|
||||
|
@ -83,16 +90,33 @@ class CommandController extends ObjectController
|
|||
$o = $this->object;
|
||||
$this->tabs()->activate('arguments');
|
||||
$this->addTitle($this->translate('Command arguments: %s'), $o->getObjectName());
|
||||
$form = IcingaCommandArgumentForm::load()->setCommandObject($o);
|
||||
if ($id = $p->shift('argument_id')) {
|
||||
$form = (new IcingaCommandArgumentForm)
|
||||
->setBranch($this->getBranch())
|
||||
->setCommandObject($o);
|
||||
if ($argument = $p->shift('argument')) {
|
||||
$this->addBackLink('director/command/arguments', [
|
||||
'name' => $p->get('name')
|
||||
]);
|
||||
$form->loadObject($id);
|
||||
if ($this->branch->isBranch()) {
|
||||
$arguments = $o->arguments();
|
||||
$argument = $arguments->get($argument);
|
||||
// IcingaCommandArgument::create((array) $arguments->get($argument)->toFullPlainObject());
|
||||
// $argument->setBeingLoadedFromDb();
|
||||
} else {
|
||||
$argument = IcingaCommandArgument::load([
|
||||
'command_id' => $o->get('id'),
|
||||
'argument_name' => $argument
|
||||
], $this->db());
|
||||
}
|
||||
$form->setObject($argument);
|
||||
}
|
||||
$form->handleRequest();
|
||||
$this->content()->add([$form]);
|
||||
IcingaCommandArgumentTable::create($o)->renderTo($this);
|
||||
if ($this->branch->isBranch()) {
|
||||
(new BranchedIcingaCommandArgumentTable($o, $this->getBranch()))->renderTo($this);
|
||||
} else {
|
||||
(new IcingaCommandArgumentTable($o, $this->getBranch()))->renderTo($this);
|
||||
}
|
||||
}
|
||||
|
||||
protected function hasBasketSupport()
|
||||
|
|
|
@ -432,6 +432,9 @@ class ConfigController extends ActionController
|
|||
|
||||
protected function showOptionalBranchActivity()
|
||||
{
|
||||
if ($this->url()->hasParam('idRangeEx')) {
|
||||
return;
|
||||
}
|
||||
$branch = $this->getBranch();
|
||||
if ($branch->isBranch() && (int) $this->params->get('page', '1') === 1) {
|
||||
$table = new BranchActivityTable($branch->getUuid(), $this->db());
|
||||
|
@ -443,12 +446,12 @@ class ConfigController extends ActionController
|
|||
$this->Auth(),
|
||||
$this->translate('configuration branch')
|
||||
))));
|
||||
$table = new BranchActivityTable($branch->getUuid(), $this->db());
|
||||
$this->content()->add($table);
|
||||
$this->content()->add(Html::tag('br'));
|
||||
$this->content()->add(Hint::ok($this->translate(
|
||||
'...and the modifications below are already in the main branch:'
|
||||
)));
|
||||
$this->content()->add(Html::tag('br'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,17 +19,11 @@ class DatafieldController extends ActionController
|
|||
|
||||
public function indexAction()
|
||||
{
|
||||
$edit = false;
|
||||
|
||||
if ($id = $this->params->get('id')) {
|
||||
$edit = true;
|
||||
}
|
||||
|
||||
$form = DirectorDatafieldForm::load()
|
||||
->setDb($this->db());
|
||||
|
||||
if ($edit) {
|
||||
$form->loadObject($id);
|
||||
if ($id = $this->params->get('id')) {
|
||||
$form->loadObject((int) $id);
|
||||
$this->addTitle(
|
||||
$this->translate('Modify %s'),
|
||||
$form->getObject()->varname
|
||||
|
|
|
@ -107,6 +107,7 @@ class HostController extends ObjectController
|
|||
$this->addTitle($this->translate('Add Service to %s'), $host->getObjectName());
|
||||
$this->content()->add(
|
||||
IcingaAddServiceForm::load()
|
||||
->setBranch($this->getBranch())
|
||||
->setHost($host)
|
||||
->setDb($this->db())
|
||||
->handleRequest()
|
||||
|
@ -199,12 +200,21 @@ class HostController extends ObjectController
|
|||
public function servicesAction()
|
||||
{
|
||||
$this->addServicesHeader();
|
||||
$db = $this->db();
|
||||
$host = $this->getHostObject();
|
||||
$this->addTitle($this->translate('Services: %s'), $host->getObjectName());
|
||||
$branch = $this->getBranch();
|
||||
if ($branch->isBranch() && $host->get('id') === null) {
|
||||
$this->content()->add(Hint::info(
|
||||
$this->translate('Managing services on new Hosts is possible only after they have been merged.')
|
||||
));
|
||||
return;
|
||||
}
|
||||
$content = $this->content();
|
||||
$table = IcingaHostServiceTable::load($host)
|
||||
->setTitle($this->translate('Individual Service objects'));
|
||||
if ($branch->isBranch()) {
|
||||
$table->setBranchUuid($branch->getUuid());
|
||||
}
|
||||
|
||||
if (count($table)) {
|
||||
$content->add($table);
|
||||
|
@ -598,7 +608,7 @@ class HostController extends ObjectController
|
|||
*/
|
||||
protected function getHostObject()
|
||||
{
|
||||
/** @var IcingaHost $this->object */
|
||||
assert($this->object instanceof IcingaHost);
|
||||
return $this->object;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use Exception;
|
||||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Forms\ImportRowModifierForm;
|
||||
use Icinga\Module\Director\Forms\ImportSourceForm;
|
||||
use Icinga\Module\Director\Hook\ImportSourceHook;
|
||||
use Icinga\Module\Director\Web\ActionBar\AutomationObjectActionBar;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
use Icinga\Module\Director\Objects\ImportSource;
|
||||
use Icinga\Module\Director\Web\Controller\BranchHelper;
|
||||
use Icinga\Module\Director\Web\Form\CloneImportSourceForm;
|
||||
use Icinga\Module\Director\Web\Table\ImportrunTable;
|
||||
use Icinga\Module\Director\Web\Table\ImportsourceHookTable;
|
||||
|
@ -18,9 +21,12 @@ use Icinga\Module\Director\Web\Widget\ImportSourceDetails;
|
|||
use InvalidArgumentException;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use ipl\Html\Error;
|
||||
use ipl\Html\Html;
|
||||
|
||||
class ImportsourceController extends ActionController
|
||||
{
|
||||
use BranchHelper;
|
||||
|
||||
/** @var ImportSource|null */
|
||||
private $importSource;
|
||||
|
||||
|
@ -85,6 +91,14 @@ class ImportsourceController extends ActionController
|
|||
$this->translate('Import source: %s'),
|
||||
$source->get('source_name')
|
||||
)->setAutorefreshInterval(10);
|
||||
$branch = $this->getBranch();
|
||||
if ($this->getBranch()->isBranch()) {
|
||||
$this->content()->add(Hint::info(Html::sprintf($this->translate(
|
||||
'Please note that importing data will take place in your main Branch.'
|
||||
. ' Modifications to Import Sources are not allowed while being in a Configuration Branch.'
|
||||
. ' To get the full functionality, please deactivate %s'
|
||||
), Branch::requireHook()->linkToBranch($branch, $this->getAuth(), $branch->getName()))));
|
||||
}
|
||||
$this->content()->add(new ImportSourceDetails($source));
|
||||
}
|
||||
|
||||
|
@ -284,7 +298,7 @@ class ImportsourceController extends ActionController
|
|||
. (int) $source->get('id');
|
||||
$this->content()->prepend(
|
||||
ImportRowModifierForm::load()->setDb($this->db())
|
||||
->loadObject($this->params->getRequired('id'))
|
||||
->loadObject((int) $this->params->getRequired('id'))
|
||||
->setListUrl($listUrl)
|
||||
->setSource($source)
|
||||
->handleRequest()
|
||||
|
|
|
@ -6,10 +6,13 @@ use gipfl\IcingaWeb2\Link;
|
|||
use Icinga\Module\Director\Forms\DirectorJobForm;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
use Icinga\Module\Director\Objects\DirectorJob;
|
||||
use Icinga\Module\Director\Web\Controller\BranchHelper;
|
||||
use Icinga\Module\Director\Web\Widget\JobDetails;
|
||||
|
||||
class JobController extends ActionController
|
||||
{
|
||||
use BranchHelper;
|
||||
|
||||
/**
|
||||
* @throws \Icinga\Exception\MissingParameterException
|
||||
* @throws \Icinga\Exception\NotFoundError
|
||||
|
@ -29,13 +32,17 @@ class JobController extends ActionController
|
|||
{
|
||||
$this
|
||||
->addSingleTab($this->translate('New Job'))
|
||||
->addTitle($this->translate('Add a new Job'))
|
||||
->content()->add(
|
||||
DirectorJobForm::load()
|
||||
->setSuccessUrl('director/job')
|
||||
->setDb($this->db())
|
||||
->handleRequest()
|
||||
);
|
||||
->addTitle($this->translate('Add a new Job'));
|
||||
if ($this->showNotInBranch($this->translate('Creating Jobs'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->content()->add(
|
||||
DirectorJobForm::load()
|
||||
->setSuccessUrl('director/job')
|
||||
->setDb($this->db())
|
||||
->handleRequest()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,16 +52,19 @@ class JobController extends ActionController
|
|||
public function editAction()
|
||||
{
|
||||
$job = $this->requireJob();
|
||||
$this
|
||||
->addJobTabs($job, 'edit')
|
||||
->addTitle($this->translate('Job: %s'), $job->get('job_name'))
|
||||
->addToBasketLink();
|
||||
if ($this->showNotInBranch($this->translate('Modifying Jobs'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$form = DirectorJobForm::load()
|
||||
->setListUrl('director/jobs')
|
||||
->setObject($job)
|
||||
->handleRequest();
|
||||
|
||||
$this
|
||||
->addJobTabs($job, 'edit')
|
||||
->addTitle($this->translate('Job: %s'), $job->get('job_name'))
|
||||
->addToBasketLink()
|
||||
->content()->add($form);
|
||||
$this->content()->add($form);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,13 +4,19 @@ namespace Icinga\Module\Director\Controllers;
|
|||
|
||||
use Exception;
|
||||
use Icinga\Module\Director\Forms\KickstartForm;
|
||||
use Icinga\Module\Director\Web\Controller\BranchHelper;
|
||||
|
||||
class KickstartController extends DashboardController
|
||||
{
|
||||
use BranchHelper;
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$this->addSingleTab($this->translate('Kickstart'))
|
||||
->addTitle($this->translate('Director Kickstart Wizard'));
|
||||
if ($this->showNotInBranch($this->translate('Kickstart'))) {
|
||||
return;
|
||||
}
|
||||
$form = KickstartForm::load();
|
||||
try {
|
||||
$form->setEndpoint($this->db()->getDeploymentEndpoint());
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectStore;
|
||||
use Icinga\Module\Director\Db\Branch\UuidLookup;
|
||||
use Icinga\Module\Director\Forms\IcingaServiceForm;
|
||||
use Icinga\Module\Director\Monitoring;
|
||||
use Icinga\Module\Director\Web\Controller\ObjectController;
|
||||
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
||||
use Icinga\Module\Director\Objects\IcingaService;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
||||
|
@ -28,65 +29,68 @@ class ServiceController extends ObjectController
|
|||
{
|
||||
if ($this->hasPermission('director/monitoring/services')) {
|
||||
$monitoring = new Monitoring();
|
||||
return $monitoring->authCanEditService($this->Auth(), $this->getParam('host'), $this->getParam('name'));
|
||||
if ($monitoring->authCanEditService($this->Auth(), $this->getParam('host'), $this->getParam('name'))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->assertPermission('director/hosts');
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if ($host = $this->params->get('host')) {
|
||||
$this->host = IcingaHost::load($host, $this->db());
|
||||
} elseif ($hostId = $this->params->get('host_id')) {
|
||||
$this->host = IcingaHost::loadWithAutoIncId($hostId, $this->db());
|
||||
} elseif ($set = $this->params->get('set')) {
|
||||
$this->set = IcingaServiceSet::load(['object_name' => $set], $this->db());
|
||||
} elseif ($apply = $this->params->get('apply')) {
|
||||
$this->apply = IcingaService::load(
|
||||
['object_name' => $apply, 'object_type' => 'template'],
|
||||
$this->db()
|
||||
);
|
||||
}
|
||||
parent::init();
|
||||
$this->loadOptionalHost();
|
||||
$this->loadOptionalSet();
|
||||
$this->addOptionalHostTabs();
|
||||
$this->addOptionalSetTabs();
|
||||
}
|
||||
|
||||
if ($this->host) {
|
||||
$hostname = $this->host->getObjectName();
|
||||
$tabs = new Tabs();
|
||||
$tabs->add('host', [
|
||||
'url' => 'director/host',
|
||||
'urlParams' => ['name' => $hostname],
|
||||
'label' => $this->translate('Host'),
|
||||
])->add('services', [
|
||||
'url' => 'director/host/services',
|
||||
'urlParams' => ['name' => $hostname],
|
||||
'label' => $this->translate('Services'),
|
||||
]);
|
||||
|
||||
$this->addParamToTabs('host', $hostname);
|
||||
$this->controls()->prependTabs($tabs);
|
||||
}
|
||||
|
||||
if ($this->object) {
|
||||
if (! $this->set && $this->object->get('service_set_id')) {
|
||||
$this->set = $this->object->getRelated('service_set');
|
||||
protected function loadOptionalHost()
|
||||
{
|
||||
$host = $this->params->get('host', $this->params->get('host_id'));
|
||||
if ($host === null && $this->object) {
|
||||
if ($host = $this->object->get('host_id')) {
|
||||
$host = (int) $host;
|
||||
} else {
|
||||
$host = $this->object->get('host');
|
||||
var_dump($host);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->set) {
|
||||
$setName = $this->set->getObjectName();
|
||||
$tabs = new Tabs();
|
||||
$tabs->add('set', [
|
||||
'url' => 'director/serviceset',
|
||||
'urlParams' => ['name' => $setName],
|
||||
'label' => $this->translate('ServiceSet'),
|
||||
])->add('services', [
|
||||
'url' => 'director/serviceset/services',
|
||||
'urlParams' => ['name' => $setName],
|
||||
'label' => $this->translate('Services'),
|
||||
]);
|
||||
if ($host !== null) {
|
||||
$key = UuidLookup::findUuidForKey($host, 'icinga_host', $this->db(), $this->getBranch());
|
||||
$this->host = $this->loadSpecificObject('icinga_host', $key);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addParamToTabs('serviceset', $setName);
|
||||
$this->controls()->prependTabs($tabs);
|
||||
protected function loadOptionalSet()
|
||||
{
|
||||
$key = $this->params->get('set', $this->params->get('service_set_id'));
|
||||
if ($key === null && $this->object && $key = $this->object->get('service_set_id')) {
|
||||
$key = (int) $key;
|
||||
}
|
||||
|
||||
if ($key !== null) {
|
||||
$uuid = UuidLookup::findUuidForKey($key, 'icinga_service_set', $this->db(), $this->getBranch());
|
||||
$this->set = $this->loadSpecificObject('icinga_service_set', $uuid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Is this still a thing? It's unused.
|
||||
*
|
||||
* @throws \Icinga\Exception\NotFoundError
|
||||
*/
|
||||
protected function loadOptionalApplyRule()
|
||||
{
|
||||
if ($apply = $this->params->get('apply')) {
|
||||
// Hint: doesn't work, DbObjectStore::load does no longer exist
|
||||
$store = new DbObjectStore($this->db(), $this->getBranch());
|
||||
$this->apply = $store->load('service', [
|
||||
'object_name' => $apply,
|
||||
'object_type' => 'template'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +108,7 @@ class ServiceController extends ObjectController
|
|||
{
|
||||
parent::addAction();
|
||||
if ($this->host) {
|
||||
// TODO: use setTitle. And figure out, where we use this old route.
|
||||
$this->view->title = $this->host->object_name . ': ' . $this->view->title;
|
||||
} elseif ($this->set) {
|
||||
$this->view->title = sprintf(
|
||||
|
@ -218,33 +223,74 @@ class ServiceController extends ObjectController
|
|||
$this->content()->add($table);
|
||||
}
|
||||
|
||||
protected function loadObject()
|
||||
protected function getLegacyKey()
|
||||
{
|
||||
if ($this->object === null) {
|
||||
if ($id = $this->params->get('id')) {
|
||||
$this->object = IcingaService::loadWithAutoIncId(
|
||||
(int) $id,
|
||||
$this->db()
|
||||
);
|
||||
} elseif ($name = $this->params->get('name')) {
|
||||
$params = array('object_name' => $name);
|
||||
$db = $this->db();
|
||||
|
||||
if ($this->host) {
|
||||
// $this->view->host = $this->host;
|
||||
$params['host_id'] = $this->host->id;
|
||||
}
|
||||
|
||||
if ($this->set) {
|
||||
// $this->view->set = $this->set;
|
||||
$params['service_set_id'] = $this->set->id;
|
||||
}
|
||||
$this->object = IcingaService::load($params, $db);
|
||||
} else {
|
||||
parent::loadObject();
|
||||
}
|
||||
if ($key = $this->params->get('id')) {
|
||||
$key = (int) $key;
|
||||
} else {
|
||||
$key = $this->params->get('name');
|
||||
}
|
||||
|
||||
return $this->object;
|
||||
if ($key === null) {
|
||||
throw new \InvalidArgumentException('uuid, name or id required');
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
protected function loadObject()
|
||||
{
|
||||
if ($this->params->has('uuid')) {
|
||||
parent::loadObject();
|
||||
return;
|
||||
}
|
||||
|
||||
$key = $this->getLegacyKey();
|
||||
$uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'object', $key, $this->host, $this->set);
|
||||
$this->params->set('uuid', $uuid->toString());
|
||||
parent::loadObject();
|
||||
}
|
||||
|
||||
protected function addOptionalHostTabs()
|
||||
{
|
||||
if ($this->host === null) {
|
||||
return;
|
||||
}
|
||||
$hostname = $this->host->getObjectName();
|
||||
$tabs = new Tabs();
|
||||
$urlParams = ['uuid' => $this->host->getUniqueId()->toString()];
|
||||
$tabs->add('host', [
|
||||
'url' => 'director/host',
|
||||
'urlParams' => $urlParams,
|
||||
'label' => $this->translate('Host'),
|
||||
])->add('services', [
|
||||
'url' => 'director/host/services',
|
||||
'urlParams' => $urlParams,
|
||||
'label' => $this->translate('Services'),
|
||||
]);
|
||||
|
||||
$this->addParamToTabs('host', $hostname);
|
||||
$this->controls()->prependTabs($tabs);
|
||||
}
|
||||
|
||||
protected function addOptionalSetTabs()
|
||||
{
|
||||
if ($this->set === null) {
|
||||
return;
|
||||
}
|
||||
$setName = $this->set->getObjectName();
|
||||
$tabs = new Tabs();
|
||||
$tabs->add('set', [
|
||||
'url' => 'director/serviceset',
|
||||
'urlParams' => ['name' => $setName],
|
||||
'label' => $this->translate('ServiceSet'),
|
||||
])->add('services', [
|
||||
'url' => 'director/serviceset/services',
|
||||
'urlParams' => ['name' => $setName],
|
||||
'label' => $this->translate('Services'),
|
||||
]);
|
||||
|
||||
$this->addParamToTabs('serviceset', $setName);
|
||||
$this->controls()->prependTabs($tabs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use gipfl\Diff\HtmlRenderer\SideBySideDiff;
|
|||
use gipfl\Diff\PhpDiff;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Module\Director\Web\Widget\IcingaConfigDiff;
|
||||
use Icinga\Module\Director\Web\Widget\UnorderedList;
|
||||
use Icinga\Module\Director\Db\Cache\PrefetchCache;
|
||||
use Icinga\Module\Director\DirectorObject\Automation\ExportInterface;
|
||||
|
@ -309,7 +310,7 @@ class SyncruleController extends ActionController
|
|||
$cfgOld = new IcingaConfig($this->db());
|
||||
$oldObject->renderToConfig($cfgOld);
|
||||
$object->renderToConfig($cfgNew);
|
||||
foreach ($this->getConfigDiffs($cfgOld, $cfgNew) as $file => $diff) {
|
||||
foreach (IcingaConfigDiff::getDiffs($cfgOld, $cfgNew) as $file => $diff) {
|
||||
$names[$name . '___PRETITLE___' . $file] = Html::tag('h3', $file);
|
||||
$names[$name . '___PREVIEW___' . $file] = $diff;
|
||||
}
|
||||
|
@ -334,7 +335,7 @@ class SyncruleController extends ActionController
|
|||
$cfgOld = new IcingaConfig($this->db());
|
||||
$oldObject->renderToConfig($cfgOld);
|
||||
$object->renderToConfig($cfgNew);
|
||||
foreach ($this->getConfigDiffs($cfgOld, $cfgNew) as $file => $diff) {
|
||||
foreach (IcingaConfigDiff::getDiffs($cfgOld, $cfgNew) as $file => $diff) {
|
||||
$names[$name . '___PRETITLE___' . $file] = Html::tag('h3', $file);
|
||||
$names[$name . '___PREVIEW___' . $file] = $diff;
|
||||
}
|
||||
|
@ -364,43 +365,6 @@ class SyncruleController extends ActionController
|
|||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stolen from elsewhere, should be de-duplicated
|
||||
*
|
||||
* @param IcingaConfig $oldConfig
|
||||
* @param IcingaConfig $newConfig
|
||||
* @return ValidHtml[]
|
||||
*/
|
||||
protected function getConfigDiffs(IcingaConfig $oldConfig, IcingaConfig $newConfig)
|
||||
{
|
||||
$oldFileNames = $oldConfig->getFileNames();
|
||||
$newFileNames = $newConfig->getFileNames();
|
||||
|
||||
$fileNames = array_merge($oldFileNames, $newFileNames);
|
||||
|
||||
$diffs = [];
|
||||
foreach ($fileNames as $filename) {
|
||||
if (in_array($filename, $oldFileNames)) {
|
||||
$left = $oldConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$left = '';
|
||||
}
|
||||
|
||||
if (in_array($filename, $newFileNames)) {
|
||||
$right = $newConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$right = '';
|
||||
}
|
||||
if ($left === $right) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$diffs[$filename] = new SideBySideDiff(new PhpDiff($left, $right));
|
||||
}
|
||||
|
||||
return $diffs;
|
||||
}
|
||||
|
||||
protected function listModifiedProperties($properties)
|
||||
{
|
||||
$list = new UnorderedList();
|
||||
|
|
|
@ -4,9 +4,12 @@ namespace Icinga\Module\Director\Controllers;
|
|||
|
||||
use Icinga\Module\Director\Forms\IcingaTemplateChoiceForm;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
use Icinga\Module\Director\Web\Controller\BranchHelper;
|
||||
|
||||
class TemplatechoiceController extends ActionController
|
||||
{
|
||||
use BranchHelper;
|
||||
|
||||
protected function checkDirectorPermissions()
|
||||
{
|
||||
$this->assertPermission('director/admin');
|
||||
|
@ -24,12 +27,15 @@ class TemplatechoiceController extends ActionController
|
|||
|
||||
protected function prepare($type, $title)
|
||||
{
|
||||
$this->addSingleTab('Choice')
|
||||
->addTitle($title);
|
||||
$form = IcingaTemplateChoiceForm::create($type, $this->db())
|
||||
->optionallyLoad($this->params->get('name'))
|
||||
->setListUrl("director/templatechoices/$type")
|
||||
->handleRequest();
|
||||
$this->addSingleTab('Choice')
|
||||
->addTitle($title)
|
||||
->content()->add($form);
|
||||
if ($this->showNotInBranch($this->translate('Modifying Template Choices'))) {
|
||||
return;
|
||||
}
|
||||
$this->content()->add($form);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,10 +161,11 @@ class IcingaAddServiceForm extends DirectorObjectForm
|
|||
$plain = $this->object->toPlainObject();
|
||||
$db = $this->object->getConnection();
|
||||
|
||||
// TODO: Test this:
|
||||
foreach ($this->hosts as $host) {
|
||||
IcingaService::fromPlainObject($plain, $db)
|
||||
->set('host_id', $host->get('id'))
|
||||
->store();
|
||||
$service = IcingaService::fromPlainObject($plain, $db)
|
||||
->set('host_id', $host->get('id'));
|
||||
$this->getDbObjectStore()->store($service);
|
||||
}
|
||||
|
||||
$msg = sprintf(
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Forms;
|
|||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Module\Director\Acl;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectStore;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
|
@ -24,7 +25,9 @@ class IcingaCloneObjectForm extends DirectorForm
|
|||
|
||||
public function setup()
|
||||
{
|
||||
if ($this->branch->isBranch() && $this->object instanceof IcingaObject && $this->object->isTemplate()) {
|
||||
$isBranch = $this->branch && $this->branch->isBranch();
|
||||
$branchOnly = $this->object->get('id') === null;
|
||||
if ($isBranch && $this->object instanceof IcingaObject && $this->object->isTemplate()) {
|
||||
$this->addHtml(Hint::error($this->translate(
|
||||
'Templates cannot be cloned in Configuration Branches'
|
||||
)));
|
||||
|
@ -38,7 +41,7 @@ class IcingaCloneObjectForm extends DirectorForm
|
|||
'value' => $name,
|
||||
));
|
||||
|
||||
if (Acl::instance()->hasPermission('director/admin')) {
|
||||
if (!$branchOnly && Acl::instance()->hasPermission('director/admin')) {
|
||||
$this->addElement('select', 'clone_type', array(
|
||||
'label' => 'Clone type',
|
||||
'required' => true,
|
||||
|
@ -49,8 +52,8 @@ class IcingaCloneObjectForm extends DirectorForm
|
|||
));
|
||||
}
|
||||
|
||||
if ($this->object instanceof IcingaHost
|
||||
|| $this->object instanceof IcingaServiceSet
|
||||
if (!$branchOnly && ($this->object instanceof IcingaHost
|
||||
|| $this->object instanceof IcingaServiceSet)
|
||||
) {
|
||||
$this->addBoolean('clone_services', [
|
||||
'label' => $this->translate('Clone Services'),
|
||||
|
@ -60,7 +63,7 @@ class IcingaCloneObjectForm extends DirectorForm
|
|||
], 'y');
|
||||
}
|
||||
|
||||
if ($this->object instanceof IcingaHost) {
|
||||
if (!$branchOnly && $this->object instanceof IcingaHost) {
|
||||
$this->addBoolean('clone_service_sets', [
|
||||
'label' => $this->translate('Clone Service Sets'),
|
||||
'description' => $this->translate(
|
||||
|
@ -139,6 +142,10 @@ class IcingaCloneObjectForm extends DirectorForm
|
|||
$object->getObjectName()
|
||||
);
|
||||
|
||||
if ($object->isTemplate() && $this->branch && $this->branch->isBranch()) {
|
||||
throw new IcingaException('Cloning templates is not available for Branches');
|
||||
}
|
||||
|
||||
if ($object->isTemplate() && $object->getObjectName() === $newName) {
|
||||
throw new IcingaException(
|
||||
$this->translate('Name needs to be changed when cloning a Template')
|
||||
|
@ -188,7 +195,8 @@ class IcingaCloneObjectForm extends DirectorForm
|
|||
$fields = [];
|
||||
}
|
||||
|
||||
if ($new->store()) {
|
||||
$store = new DbObjectStore($connection, $this->branch);
|
||||
if ($store->store($new)) {
|
||||
$newId = $new->get('id');
|
||||
foreach ($services as $service) {
|
||||
$clone = IcingaService::fromPlainObject(
|
||||
|
@ -201,14 +209,15 @@ class IcingaCloneObjectForm extends DirectorForm
|
|||
} elseif ($new instanceof IcingaServiceSet) {
|
||||
$clone->set('service_set_id', $newId);
|
||||
}
|
||||
$clone->store();
|
||||
$store->store($clone);
|
||||
}
|
||||
|
||||
foreach ($sets as $set) {
|
||||
IcingaServiceSet::fromPlainObject(
|
||||
$newSet = IcingaServiceSet::fromPlainObject(
|
||||
$set->toPlainObject(),
|
||||
$connection
|
||||
)->set('host_id', $newId)->store();
|
||||
)->set('host_id', $newId);
|
||||
$store->store($newSet);
|
||||
}
|
||||
|
||||
foreach ($fields as $row) {
|
||||
|
|
|
@ -134,16 +134,22 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
|
|||
$cmd = $this->commandObject;
|
||||
|
||||
$msg = sprintf(
|
||||
'%s argument "%s" has been removed',
|
||||
$this->translate('%s argument "%s" has been removed'),
|
||||
$this->translate($this->getObjectShortClassName()),
|
||||
$object->argument_name
|
||||
);
|
||||
|
||||
$url = $this->getSuccessUrl()->without('argument_id');
|
||||
// TODO: remove argument_id, once verified that it is no longer in use
|
||||
$url = $this->getSuccessUrl()->without('argument_id')->without('argument');
|
||||
|
||||
$cmd->arguments()->remove($object->argument_name);
|
||||
if ($cmd->store()) {
|
||||
if ($this->branch->isBranch()) {
|
||||
$this->getDbObjectStore()->store($cmd);
|
||||
$this->setSuccessUrl($url);
|
||||
} else {
|
||||
if ($cmd->store()) {
|
||||
$this->setSuccessUrl($url);
|
||||
}
|
||||
}
|
||||
|
||||
$this->redirectOnSuccess($msg);
|
||||
|
@ -167,20 +173,17 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
|
|||
$this->translate('The argument %s has successfully been stored'),
|
||||
$object->get('argument_name')
|
||||
);
|
||||
$cmd->store($this->db);
|
||||
$this->getDbObjectStore()->store($cmd);
|
||||
} else {
|
||||
if ($this->isApiRequest()) {
|
||||
$this->setHttpResponseCode(304);
|
||||
}
|
||||
$msg = $this->translate('No action taken, object has not been modified');
|
||||
}
|
||||
$this->setSuccessUrl(
|
||||
'director/command/arguments',
|
||||
[
|
||||
'argument_id' => $object->get('id'),
|
||||
'name' => $cmd->getObjectName()
|
||||
]
|
||||
);
|
||||
$this->setSuccessUrl('director/command/arguments', [
|
||||
'argument' => $object->get('argument_name'),
|
||||
'name' => $cmd->getObjectName()
|
||||
]);
|
||||
|
||||
$this->redirectOnSuccess($msg);
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
|||
$vars->vars[$row->varname] = CustomVariable::fromDbRow($row);
|
||||
}
|
||||
$vars->refreshIndex();
|
||||
$vars->setUnmodified();
|
||||
$vars->setBeingLoadedFromDb();
|
||||
return $vars;
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
|||
$vars->vars[$row->varname] = CustomVariable::fromDbRow($row);
|
||||
}
|
||||
$vars->refreshIndex();
|
||||
$vars->setUnmodified();
|
||||
$vars->setBeingLoadedFromDb();
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
|||
}
|
||||
}
|
||||
|
||||
$this->setUnmodified();
|
||||
$this->setBeingLoadedFromDb();
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
|
@ -264,14 +264,16 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
|||
return false;
|
||||
}
|
||||
|
||||
public function setUnmodified()
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
$this->modified = false;
|
||||
$this->storedVars = array();
|
||||
foreach ($this->vars as $key => $var) {
|
||||
$this->storedVars[$key] = clone($var);
|
||||
$var->setUnmodified();
|
||||
$var->setLoadedFromDb();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
namespace Icinga\Module\Director\Data\Db;
|
||||
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Module\Director\Data\InvalidDataException;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Exception\DuplicateKeyException;
|
||||
use Icinga\Module\Director\Util;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use RuntimeException;
|
||||
use Zend_Db_Adapter_Abstract;
|
||||
use Zend_Db_Exception;
|
||||
|
@ -69,6 +71,9 @@ abstract class DbObject
|
|||
*/
|
||||
protected $autoincKeyName;
|
||||
|
||||
/** @var string optional uuid column */
|
||||
protected $uuidColumn;
|
||||
|
||||
/** @var bool forbid updates to autoinc values */
|
||||
protected $protectAutoinc = true;
|
||||
|
||||
|
@ -307,6 +312,9 @@ abstract class DbObject
|
|||
$value = null;
|
||||
}
|
||||
|
||||
if (is_resource($value)) {
|
||||
$value = stream_get_contents($value);
|
||||
}
|
||||
$func = 'validate' . ucfirst($key);
|
||||
if (method_exists($this, $func) && $this->$func($value) !== true) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
|
@ -530,6 +538,44 @@ abstract class DbObject
|
|||
return $this->autoincKeyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?string
|
||||
*/
|
||||
public function getUuidColumn()
|
||||
{
|
||||
return $this->uuidColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUuidColumn()
|
||||
{
|
||||
return $this->uuidColumn !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Ramsey\Uuid\UuidInterface
|
||||
*/
|
||||
public function getUniqueId()
|
||||
{
|
||||
if ($this->hasUuidColumn()) {
|
||||
$binaryValue = $this->properties[$this->uuidColumn];
|
||||
if (is_resource($binaryValue)) {
|
||||
throw new RuntimeException('Properties contain binary UUID, probably a programming error');
|
||||
}
|
||||
if ($binaryValue === null) {
|
||||
$uuid = Uuid::uuid4();
|
||||
$this->reallySet($this->uuidColumn, $uuid->getBytes());
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
return Uuid::fromBytes($binaryValue);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('%s has no UUID column', $this->getTableName()));
|
||||
}
|
||||
|
||||
public function getKeyParams()
|
||||
{
|
||||
$params = array();
|
||||
|
@ -651,15 +697,22 @@ abstract class DbObject
|
|||
}
|
||||
|
||||
/**
|
||||
* @param object $row
|
||||
* @param object|array $row
|
||||
* @param Db $db
|
||||
* @return self
|
||||
*/
|
||||
public static function fromDbRow($row, Db $db)
|
||||
{
|
||||
return (new static())
|
||||
->setConnection($db)
|
||||
->setDbProperties($row);
|
||||
$self = (new static())->setConnection($db);
|
||||
if (is_object($row)) {
|
||||
return $self->setDbProperties((array) $row);
|
||||
}
|
||||
|
||||
if (is_array($row)) {
|
||||
return $self->setDbProperties($row);
|
||||
}
|
||||
|
||||
throw new InvalidDataException('array or object', $row);
|
||||
}
|
||||
|
||||
protected function setDbProperties($properties)
|
||||
|
@ -694,6 +747,16 @@ abstract class DbObject
|
|||
$this->modifiedProperties = [];
|
||||
}
|
||||
|
||||
public function setLoadedProperty($key, $value)
|
||||
{
|
||||
if ($this->hasBeenLoadedFromDb()) {
|
||||
$this->set($key, $value);
|
||||
$this->loadedProperties[$key] = $this->get($key);
|
||||
} else {
|
||||
throw new RuntimeException('Cannot set loaded property for new object');
|
||||
}
|
||||
}
|
||||
|
||||
public function getOriginalProperties()
|
||||
{
|
||||
return $this->loadedProperties;
|
||||
|
@ -737,6 +800,7 @@ abstract class DbObject
|
|||
// Fake true, we might have manually set this to "modified"
|
||||
return true;
|
||||
}
|
||||
$this->quoteBinaryProperties($properties);
|
||||
|
||||
// TODO: Remember changed data for audit and log
|
||||
return $this->db->update(
|
||||
|
@ -760,18 +824,23 @@ abstract class DbObject
|
|||
unset($properties[$this->autoincKeyName]);
|
||||
}
|
||||
}
|
||||
$this->quoteBinaryProperties($properties);
|
||||
|
||||
return $this->db->insert($this->table, $properties);
|
||||
}
|
||||
|
||||
protected function quoteBinaryProperties(&$properties)
|
||||
{
|
||||
foreach ($properties as $key => $value) {
|
||||
if ($this->isBinaryColumn($key)) {
|
||||
$properties[$key] = $this->getConnection()->quoteBinary($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->db->insert($this->table, $properties);
|
||||
}
|
||||
|
||||
protected function isBinaryColumn($column)
|
||||
{
|
||||
return in_array($column, $this->binaryProperties);
|
||||
return in_array($column, $this->binaryProperties) || $this->getUuidColumn() === $column;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1273,6 +1342,69 @@ abstract class DbObject
|
|||
return $obj->existsInDb();
|
||||
}
|
||||
|
||||
public static function uniqueIdExists(UuidInterface $uuid, DbConnection $connection)
|
||||
{
|
||||
$db = $connection->getDbAdapter();
|
||||
$obj = new static;
|
||||
$column = $obj->getUuidColumn();
|
||||
$query = $db->select()
|
||||
->from($obj->getTableName(), $column)
|
||||
->where("$column = ?", $connection->quoteBinary($uuid->getBytes()));
|
||||
|
||||
$result = $db->fetchRow($query);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
public static function requireWithUniqueId(UuidInterface $uuid, DbConnection $connection)
|
||||
{
|
||||
if ($object = static::loadWithUniqueId($uuid, $connection)) {
|
||||
return $object;
|
||||
}
|
||||
|
||||
throw new NotFoundError(sprintf(
|
||||
'No %s with UUID=%s has been found',
|
||||
(new static)->getTableName(),
|
||||
$uuid->toString()
|
||||
));
|
||||
}
|
||||
|
||||
public static function loadWithUniqueId(UuidInterface $uuid, DbConnection $connection)
|
||||
{
|
||||
$db = $connection->getDbAdapter();
|
||||
$obj = new static;
|
||||
$query = $db->select()
|
||||
->from($obj->getTableName())
|
||||
->where($obj->getUuidColumn() . ' = ?', $connection->quoteBinary($uuid->getBytes()));
|
||||
|
||||
$result = $db->fetchRow($query);
|
||||
|
||||
if ($result) {
|
||||
return $obj->setConnection($connection)->setDbProperties($result);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setUniqueId(UuidInterface $uuid)
|
||||
{
|
||||
if ($column = $this->getUuidColumn()) {
|
||||
$binary = $uuid->getBytes();
|
||||
$current = $this->get($column);
|
||||
if ($current === null) {
|
||||
$this->set($column, $binary);
|
||||
} else {
|
||||
if ($current !== $binary) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Changing the UUID (from %s to %s) is not allowed',
|
||||
Uuid::fromBytes($current)->toString(),
|
||||
Uuid::fromBytes($binary)->toString()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
unset($this->db);
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
namespace Icinga\Module\Director\Data\Db;
|
||||
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Db\Branch\BranchModificationStore;
|
||||
use Icinga\Module\Director\Db\Branch\IcingaObjectModification;
|
||||
use function in_array;
|
||||
use Icinga\Module\Director\Db\Branch\BranchActivity;
|
||||
use Icinga\Module\Director\Db\Branch\BranchedObject;
|
||||
|
||||
/**
|
||||
* Loader for Icinga/DbObjects
|
||||
|
@ -21,96 +19,46 @@ class DbObjectStore
|
|||
/** @var Db */
|
||||
protected $connection;
|
||||
|
||||
/** @var Branch */
|
||||
/** @var ?Branch */
|
||||
protected $branch;
|
||||
|
||||
public function __construct(Db $connection)
|
||||
public function __construct(Db $connection, Branch $branch = null)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function setBranch(Branch $branch)
|
||||
{
|
||||
$this->branch = $branch;
|
||||
}
|
||||
|
||||
protected function typeSupportsBranches($type)
|
||||
public function store(DbObject $object)
|
||||
{
|
||||
return in_array($type, ['host', 'user', 'zone', 'timeperiod']);
|
||||
}
|
||||
if ($this->branch && $this->branch->isBranch()) {
|
||||
$activity = BranchActivity::forDbObject($object, $this->branch);
|
||||
$this->connection->runFailSafeTransaction(function () use ($activity) {
|
||||
$activity->store($this->connection);
|
||||
BranchedObject::withActivity($activity, $this->connection)->store($this->connection);
|
||||
});
|
||||
|
||||
/**
|
||||
* @param string $shortType
|
||||
* @param string|array $key
|
||||
* @return DbObject
|
||||
* @throws NotFoundError
|
||||
*/
|
||||
public function load($shortType, $key)
|
||||
{
|
||||
return $this->loadWithBranchModification($shortType, $key)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $shortType
|
||||
* @param int|string|array $key
|
||||
* @return array
|
||||
* @throws NotFoundError
|
||||
*/
|
||||
public function loadWithBranchModification($shortType, $key)
|
||||
{
|
||||
/** @var string|DbObject $class */
|
||||
$class = DbObjectTypeRegistry::classByType($shortType);
|
||||
if ($this->branch && $this->branch->isBranch() && $this->typeSupportsBranches($shortType) && is_string($key)) {
|
||||
$branchStore = new BranchModificationStore($this->connection, $shortType);
|
||||
return true;
|
||||
} else {
|
||||
$branchStore = null;
|
||||
return $object->store($this->connection);
|
||||
}
|
||||
$modification = null;
|
||||
try {
|
||||
if (is_int($key)) {
|
||||
$object = $class::loadWithAutoIncId($key, $this->connection);
|
||||
} else {
|
||||
$object = $class::load($key, $this->connection);
|
||||
}
|
||||
if ($branchStore && $modification = $branchStore->eventuallyLoadModification(
|
||||
$object->get('id'),
|
||||
$this->branch->getUuid()
|
||||
)) {
|
||||
$object = IcingaObjectModification::applyModification($modification, $object, $this->connection);
|
||||
}
|
||||
} catch (NotFoundError $e) {
|
||||
if ($this->branch && $this->branch->isBranch() && is_string($key)) {
|
||||
$branchStore = new BranchModificationStore($this->connection, $shortType);
|
||||
$modification = $branchStore->loadOptionalModificationByName($key, $this->branch->getUuid());
|
||||
if ($modification) {
|
||||
$object = IcingaObjectModification::applyModification($modification, null, $this->connection);
|
||||
$object->setConnection($this->connection);
|
||||
if ($id = $object->get('id')) { // Object has probably been renamed
|
||||
try {
|
||||
// TODO: can be one step I guess, but my brain is slow today ;-)
|
||||
$renamedObject = $class::load($id, $this->connection);
|
||||
$object = IcingaObjectModification::applyModification(
|
||||
$modification,
|
||||
$renamedObject,
|
||||
$this->connection
|
||||
);
|
||||
} catch (NotFoundError $e) {
|
||||
// Well... it was worth trying
|
||||
$object->setConnection($this->connection);
|
||||
$object->setBeingLoadedFromDb();
|
||||
}
|
||||
} else {
|
||||
$object->setConnection($this->connection);
|
||||
$object->setBeingLoadedFromDb();
|
||||
}
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(DbObject $object)
|
||||
{
|
||||
if ($this->branch && $this->branch->isBranch()) {
|
||||
$activity = BranchActivity::deleteObject($object, $this->branch);
|
||||
$this->connection->runFailSafeTransaction(function () use ($activity) {
|
||||
$activity->store($this->connection);
|
||||
BranchedObject::load(
|
||||
$this->connection,
|
||||
$activity->getObjectTable(),
|
||||
$activity->getObjectUuid(),
|
||||
$this->branch
|
||||
)->delete($this->connection);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return [$object, $modification];
|
||||
return $object->delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,14 @@
|
|||
namespace Icinga\Module\Director\Data\Db;
|
||||
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
|
||||
class DbObjectTypeRegistry
|
||||
{
|
||||
/**
|
||||
* @param $type
|
||||
* @return string|DbObject Fake typehint for IDE
|
||||
*/
|
||||
public static function classByType($type)
|
||||
{
|
||||
// allow for icinga_host and host
|
||||
|
@ -44,6 +49,23 @@ class DbObjectTypeRegistry
|
|||
return 'Icinga\\Module\\Director\\Objects\\' . $prefix . ucfirst($type);
|
||||
}
|
||||
|
||||
public static function tableNameByType($type)
|
||||
{
|
||||
$class = static::classByType($type);
|
||||
$dummy = $class::create([]);
|
||||
|
||||
return $dummy->getTableName();
|
||||
}
|
||||
|
||||
public static function shortTypeForObject(DbObject $object)
|
||||
{
|
||||
if ($object instanceof IcingaObject) {
|
||||
return $object->getShortTableName();
|
||||
}
|
||||
|
||||
return $object->getTableName();
|
||||
}
|
||||
|
||||
public static function newObject($type, $properties = [], Db $db = null)
|
||||
{
|
||||
/** @var DbObject $class fake hint for the IDE, it's a string */
|
||||
|
|
|
@ -52,4 +52,18 @@ class Json
|
|||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
* @return ?string
|
||||
* @throws JsonEncodeException
|
||||
*/
|
||||
public static function decodeOptional($string)
|
||||
{
|
||||
if ($string === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return static::decode($string);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ class Branch
|
|||
/** @var @var string */
|
||||
protected $description;
|
||||
|
||||
/** @var bool */
|
||||
protected $shouldBeMerged;
|
||||
/** @var ?int */
|
||||
protected $tsMergeRequest;
|
||||
|
||||
/** @var int */
|
||||
protected $cntActivities;
|
||||
|
@ -39,10 +39,16 @@ class Branch
|
|||
public static function fromDbRow(stdClass $row)
|
||||
{
|
||||
$self = new static;
|
||||
if (is_resource($row->uuid)) {
|
||||
$row->uuid = stream_get_contents($row->uuid);
|
||||
}
|
||||
if (strlen($row->uuid) !== 16) {
|
||||
throw new RuntimeException('Valid UUID expected, got ' . var_export($row->uuid, 1));
|
||||
}
|
||||
$self->branchUuid = Uuid::fromBytes($row->uuid);
|
||||
$self->name = $row->branch_name;
|
||||
$self->owner = $row->owner;
|
||||
$self->shouldBeMerged = $row->should_be_merged === 'y';
|
||||
$self->tsMergeRequest = $row->ts_merge_request;
|
||||
if (isset($row->cnt_activities)) {
|
||||
$self->cntActivities = $row->cnt_activities;
|
||||
} else {
|
||||
|
@ -118,6 +124,13 @@ class Branch
|
|||
return $this->branchUuid !== null;
|
||||
}
|
||||
|
||||
public function assertBranch()
|
||||
{
|
||||
if ($this->isMain()) {
|
||||
throw new RuntimeException('Branch expected, but working in main branch');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -131,7 +144,7 @@ class Branch
|
|||
*/
|
||||
public function shouldBeMerged()
|
||||
{
|
||||
return $this->shouldBeMerged;
|
||||
return $this->tsMergeRequest !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,376 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
|
||||
use Icinga\Module\Director\Data\Json;
|
||||
use Icinga\Module\Director\Data\SerializableValue;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use InvalidArgumentException;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use RuntimeException;
|
||||
|
||||
class BranchActivity
|
||||
{
|
||||
const DB_TABLE = 'director_branch_activity';
|
||||
|
||||
const ACTION_CREATE = 'create';
|
||||
const ACTION_MODIFY = 'modify';
|
||||
const ACTION_DELETE = 'delete';
|
||||
|
||||
/** @var int */
|
||||
protected $timestampNs;
|
||||
|
||||
/** @var UuidInterface */
|
||||
protected $objectUuid;
|
||||
|
||||
/** @var UuidInterface */
|
||||
protected $branchUuid;
|
||||
|
||||
/** @var string create, modify, delete */
|
||||
protected $action;
|
||||
|
||||
/** @var string */
|
||||
protected $objectTable;
|
||||
|
||||
/** @var string */
|
||||
protected $author;
|
||||
|
||||
/** @var SerializableValue */
|
||||
protected $modifiedProperties;
|
||||
|
||||
/** @var ?SerializableValue */
|
||||
protected $formerProperties;
|
||||
|
||||
public function __construct(
|
||||
UuidInterface $objectUuid,
|
||||
UuidInterface $branchUuid,
|
||||
$action,
|
||||
$objectType,
|
||||
$author,
|
||||
SerializableValue $modifiedProperties,
|
||||
SerializableValue $formerProperties
|
||||
) {
|
||||
$this->objectUuid = $objectUuid;
|
||||
$this->branchUuid = $branchUuid;
|
||||
$this->action = $action;
|
||||
$this->objectTable = $objectType;
|
||||
$this->author = $author;
|
||||
$this->modifiedProperties = $modifiedProperties;
|
||||
$this->formerProperties = $formerProperties;
|
||||
}
|
||||
|
||||
public static function deleteObject(DbObject $object, Branch $branch)
|
||||
{
|
||||
return new static(
|
||||
$object->getUniqueId(),
|
||||
$branch->getUuid(),
|
||||
self::ACTION_DELETE,
|
||||
$object->getTableName(),
|
||||
Auth::getInstance()->getUser()->getUsername(),
|
||||
SerializableValue::fromSerialization(null),
|
||||
SerializableValue::fromSerialization(self::getFormerObjectProperties($object))
|
||||
);
|
||||
}
|
||||
|
||||
public static function forDbObject(DbObject $object, Branch $branch)
|
||||
{
|
||||
if (! $object->hasBeenModified()) {
|
||||
throw new InvalidArgumentException('Cannot get modifications for unmodified object');
|
||||
}
|
||||
if (! $branch->isBranch()) {
|
||||
throw new InvalidArgumentException('Branch activity requires an active branch');
|
||||
}
|
||||
|
||||
$author = Auth::getInstance()->getUser()->getUsername();
|
||||
if ($object instanceof IcingaObject && $object->shouldBeRemoved()) {
|
||||
$action = self::ACTION_DELETE;
|
||||
$old = self::getFormerObjectProperties($object);
|
||||
$new = null;
|
||||
} elseif ($object->hasBeenLoadedFromDb()) {
|
||||
$action = self::ACTION_MODIFY;
|
||||
$old = self::getFormerObjectProperties($object);
|
||||
$new = self::getObjectProperties($object);
|
||||
} else {
|
||||
$action = self::ACTION_CREATE;
|
||||
$old = null;
|
||||
$new = self::getObjectProperties($object);
|
||||
}
|
||||
|
||||
if ($new !== null) {
|
||||
$new = PlainObjectPropertyDiff::calculate(
|
||||
$old,
|
||||
$new
|
||||
);
|
||||
}
|
||||
|
||||
return new static(
|
||||
$object->getUniqueId(),
|
||||
$branch->getUuid(),
|
||||
$action,
|
||||
$object->getTableName(),
|
||||
$author,
|
||||
SerializableValue::fromSerialization($new),
|
||||
SerializableValue::fromSerialization($old)
|
||||
);
|
||||
}
|
||||
|
||||
public function applyToDbObject(DbObject $object)
|
||||
{
|
||||
if (!$this->isActionModify()) {
|
||||
throw new RuntimeException('Only BranchActivity instances with action=modify can be applied');
|
||||
}
|
||||
|
||||
foreach ($this->getModifiedProperties()->jsonSerialize() as $key => $value) {
|
||||
$object->set($key, $value);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function createDbObject()
|
||||
{
|
||||
if (!$this->isActionCreate()) {
|
||||
throw new RuntimeException('Only BranchActivity instances with action=create can create objects');
|
||||
}
|
||||
|
||||
$class = DbObjectTypeRegistry::classByType($this->getObjectTable());
|
||||
$object = $class::create();
|
||||
$object->setUniqueId($this->getObjectUuid());
|
||||
foreach ($this->getModifiedProperties()->jsonSerialize() as $key => $value) {
|
||||
$object->set($key, $value);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function deleteDbObject(Db $connection)
|
||||
{
|
||||
if (!$this->isActionDelete()) {
|
||||
throw new RuntimeException('Only BranchActivity instances with action=delete can delete objects');
|
||||
}
|
||||
|
||||
$db = $connection->getDbAdapter();
|
||||
return $db->delete($this->getObjectTable(), $db->quoteInto(
|
||||
'uuid = ?',
|
||||
$connection->quoteBinary($this->getObjectUuid()->getBytes())
|
||||
));
|
||||
}
|
||||
|
||||
public static function load($ts, Db $connection)
|
||||
{
|
||||
$db = $connection->getDbAdapter();
|
||||
$row = $db->fetchRow(
|
||||
$db->select()->from('director_branch_activity')->where('timestamp_ns = ?', $ts)
|
||||
);
|
||||
|
||||
if ($row) {
|
||||
return static::fromDbRow($row);
|
||||
}
|
||||
|
||||
throw new NotFoundError('Not found');
|
||||
}
|
||||
|
||||
protected static function fixPgResource(&$value)
|
||||
{
|
||||
if (is_resource($value)) {
|
||||
$value = stream_get_contents($value);
|
||||
}
|
||||
}
|
||||
|
||||
public static function fromDbRow($row)
|
||||
{
|
||||
static::fixPgResource($row->object_uuid);
|
||||
static::fixPgResource($row->branch_uuid);
|
||||
$activity = new static(
|
||||
Uuid::fromBytes($row->object_uuid),
|
||||
Uuid::fromBytes($row->branch_uuid),
|
||||
$row->action,
|
||||
$row->object_table,
|
||||
$row->author,
|
||||
SerializableValue::fromSerialization(Json::decodeOptional($row->modified_properties)),
|
||||
SerializableValue::fromSerialization(Json::decodeOptional($row->former_properties))
|
||||
);
|
||||
$activity->timestampNs = $row->timestamp_ns;
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be run in a transaction! Repeatable read?
|
||||
* @param Db $connection
|
||||
* @throws \Icinga\Module\Director\Exception\JsonEncodeException
|
||||
* @throws \Zend_Db_Adapter_Exception
|
||||
*/
|
||||
public function store(Db $connection)
|
||||
{
|
||||
if ($this->timestampNs !== null) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Cannot store activity with a given timestamp: %s',
|
||||
$this->timestampNs
|
||||
));
|
||||
}
|
||||
$db = $connection->getDbAdapter();
|
||||
$last = $db->fetchRow(
|
||||
$db->select()->from('director_branch_activity', ['timestamp_ns' => 'MAX(timestamp_ns)'])
|
||||
);
|
||||
if (PHP_INT_SIZE !== 8) {
|
||||
throw new RuntimeException('PHP with 64bit integer support is required');
|
||||
}
|
||||
$timestampNs = (int) floor(microtime(true) * 1000000);
|
||||
if ($last) {
|
||||
if ($last->timestamp_ns >= $timestampNs) {
|
||||
$timestampNs = $last + 1;
|
||||
}
|
||||
}
|
||||
$old = Json::encode($this->formerProperties);
|
||||
$new = Json::encode($this->modifiedProperties);
|
||||
|
||||
$db->insert(self::DB_TABLE, [
|
||||
'timestamp_ns' => $timestampNs,
|
||||
'object_uuid' => $connection->quoteBinary($this->objectUuid->getBytes()),
|
||||
'branch_uuid' => $connection->quoteBinary($this->branchUuid->getBytes()),
|
||||
'action' => $this->action,
|
||||
'object_table' => $this->objectTable,
|
||||
'author' => $this->author,
|
||||
'former_properties' => $old,
|
||||
'modified_properties' => $new,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestampNs()
|
||||
{
|
||||
return $this->timestampNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestamp()
|
||||
{
|
||||
return (int) floor($this->timestampNs / 1000000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UuidInterface
|
||||
*/
|
||||
public function getObjectUuid()
|
||||
{
|
||||
return $this->objectUuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UuidInterface
|
||||
*/
|
||||
public function getBranchUuid()
|
||||
{
|
||||
return $this->branchUuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getObjectName()
|
||||
{
|
||||
return $this->getProperty('object_name', 'unknown object name');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
public function isActionDelete()
|
||||
{
|
||||
return $this->action === self::ACTION_DELETE;
|
||||
}
|
||||
|
||||
public function isActionCreate()
|
||||
{
|
||||
return $this->action === self::ACTION_CREATE;
|
||||
}
|
||||
|
||||
public function isActionModify()
|
||||
{
|
||||
return $this->action === self::ACTION_MODIFY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getObjectTable()
|
||||
{
|
||||
return $this->objectTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthor()
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?SerializableValue
|
||||
*/
|
||||
public function getModifiedProperties()
|
||||
{
|
||||
return $this->modifiedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?SerializableValue
|
||||
*/
|
||||
public function getFormerProperties()
|
||||
{
|
||||
return $this->formerProperties;
|
||||
}
|
||||
|
||||
public function getProperty($key, $default = null)
|
||||
{
|
||||
if ($this->modifiedProperties) {
|
||||
$properties = $this->modifiedProperties->jsonSerialize();
|
||||
if (isset($properties->$key)) {
|
||||
return $properties->$key;
|
||||
}
|
||||
}
|
||||
if ($this->formerProperties) {
|
||||
$properties = $this->formerProperties->jsonSerialize();
|
||||
if (isset($properties->$key)) {
|
||||
return $properties->$key;
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
protected static function getFormerObjectProperties(DbObject $object)
|
||||
{
|
||||
if (! $object instanceof IcingaObject) {
|
||||
throw new RuntimeException('Plain object helpers for DbObject must be implemented');
|
||||
}
|
||||
|
||||
return (array) $object->getPlainUnmodifiedObject();
|
||||
}
|
||||
|
||||
protected static function getObjectProperties(DbObject $object)
|
||||
{
|
||||
if (! $object instanceof IcingaObject) {
|
||||
throw new RuntimeException('Plain object helpers for DbObject must be implemented');
|
||||
}
|
||||
|
||||
return (array) $object->toPlainObject(false, true);
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Module\Director\Data\Json;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class BranchActivityStore
|
||||
{
|
||||
protected $connection;
|
||||
|
||||
protected $db;
|
||||
|
||||
protected $table = 'director_branch_activity';
|
||||
|
||||
public function __construct(Db $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->db = $connection->getDbAdapter();
|
||||
}
|
||||
|
||||
public function count(UuidInterface $branchUuid)
|
||||
{
|
||||
$query = $this->db->select()
|
||||
->from($this->table, ['cnt' => 'COUNT(*)'])
|
||||
->where('branch_uuid = ?', $branchUuid->getBytes());
|
||||
|
||||
return (int) $this->db->fetchOne($query);
|
||||
}
|
||||
|
||||
public function loadAll(UuidInterface $branchUuid)
|
||||
{
|
||||
$query = $this->db->select()
|
||||
->from($this->table)
|
||||
->where('branch_uuid = ?', $branchUuid->getBytes())
|
||||
->order('change_time DESC');
|
||||
return $this->db->fetchAll($query);
|
||||
}
|
||||
|
||||
public static function objectModificationForDbRow($row)
|
||||
{
|
||||
$modification = ObjectModification::fromSerialization(json_decode($row->change_set));
|
||||
return $modification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be run in a transaction!
|
||||
*
|
||||
* @param ObjectModification $modification
|
||||
* @param UuidInterface $branchUuid
|
||||
* @throws \Icinga\Module\Director\Exception\JsonEncodeException
|
||||
* @throws \Zend_Db_Adapter_Exception
|
||||
*/
|
||||
public function persistModification(ObjectModification $modification, UuidInterface $branchUuid)
|
||||
{
|
||||
$db = $this->db;
|
||||
$last = $db->fetchOne(
|
||||
$db->select()
|
||||
->from('director_branch_activity', 'checksum')
|
||||
->order('change_time DESC')
|
||||
->order('uuid') // Just in case, this gives a guaranteed order
|
||||
);
|
||||
// TODO: eventually implement more checks, allow only one change per millisecond
|
||||
// alternatively use last change_time plus one, when now < change_time
|
||||
if (strlen($last) !== 20) {
|
||||
$last = '';
|
||||
}
|
||||
$binaryUuid = Uuid::uuid4()->getBytes();
|
||||
$timestampMs = $this->now();
|
||||
$encoded = Json::encode($modification);
|
||||
|
||||
// HINT: checksums are useless! -> merge only
|
||||
$this->db->insert('director_branch_activity', [
|
||||
'uuid' => $binaryUuid,
|
||||
'branch_uuid' => $branchUuid->getBytes(),
|
||||
'change_set' => $encoded, // TODO: rename -> object_modification
|
||||
'change_time' => $timestampMs, // TODO: ns!!
|
||||
'checksum' => sha1("$last/$binaryUuid/$timestampMs/$encoded", true),
|
||||
'parent_checksum' => $last === '' ? null : $last,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function now()
|
||||
{
|
||||
return floor(microtime(true) * 1000);
|
||||
}
|
||||
}
|
|
@ -3,9 +3,9 @@
|
|||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Data\InvalidDataException;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class BranchMerger
|
||||
|
@ -20,7 +20,7 @@ class BranchMerger
|
|||
protected $db;
|
||||
|
||||
/** @var array */
|
||||
protected $ignoreUuids = [];
|
||||
protected $ignoreActivities = [];
|
||||
|
||||
/** @var bool */
|
||||
protected $ignoreDeleteWhenMissing = false;
|
||||
|
@ -64,88 +64,76 @@ class BranchMerger
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $uuids
|
||||
* @param int $key
|
||||
*/
|
||||
public function ignoreUuids(array $uuids)
|
||||
public function ignoreActivity($key)
|
||||
{
|
||||
foreach ($uuids as $uuid) {
|
||||
$this->ignoreUuid($uuid);
|
||||
}
|
||||
$this->ignoreActivities[$key] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UuidInterface|string $uuid
|
||||
* @param BranchActivity $activity
|
||||
* @return bool
|
||||
*/
|
||||
public function ignoreUuid($uuid)
|
||||
public function ignoresActivity(BranchActivity $activity)
|
||||
{
|
||||
if (is_string($uuid)) {
|
||||
$uuid = Uuid::fromString($uuid);
|
||||
} elseif (! ($uuid instanceof UuidInterface)) {
|
||||
throw new InvalidDataException('UUID', $uuid);
|
||||
}
|
||||
$binary = $uuid->getBytes();
|
||||
$this->ignoreUuids[$binary] = $binary;
|
||||
return isset($this->ignoreActivities[$activity->getTimestampNs()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws MergeError
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function merge()
|
||||
{
|
||||
$this->connection->runFailSafeTransaction(function () {
|
||||
$activities = new BranchActivityStore($this->connection);
|
||||
$rows = $activities->loadAll($this->branchUuid);
|
||||
$query = $this->db->select()
|
||||
->from(BranchActivity::DB_TABLE)
|
||||
->where('branch_uuid = ?', $this->connection->quoteBinary($this->branchUuid->getBytes()))
|
||||
->order('timestamp_ns ASC');
|
||||
$rows = $this->db->fetchAll($query);
|
||||
foreach ($rows as $row) {
|
||||
$modification = BranchActivityStore::objectModificationForDbRow($row);
|
||||
$this->applyModification($modification, Uuid::fromBytes($row->uuid));
|
||||
$activity = BranchActivity::fromDbRow($row);
|
||||
$this->applyModification($activity);
|
||||
}
|
||||
$this->db->delete('director_branch', $this->db->quoteInto('uuid = ?', $this->branchUuid->getBytes()));
|
||||
(new BranchStore($this->connection))->deleteByUuid($this->branchUuid);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectModification $modification
|
||||
* @param UuidInterface $uuid
|
||||
* @param BranchActivity $activity
|
||||
* @throws MergeError
|
||||
* @throws \Icinga\Exception\NotFoundError
|
||||
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||
*/
|
||||
protected function applyModification(ObjectModification $modification, UuidInterface $uuid)
|
||||
protected function applyModification(BranchActivity $activity)
|
||||
{
|
||||
$binaryUuid = $uuid->getBytes();
|
||||
/** @var string|DbObject $class */
|
||||
$class = $modification->getClassName();
|
||||
$keyParams = (array) $modification->getKeyParams();
|
||||
if (array_keys($keyParams) === ['object_name']) {
|
||||
$keyParams = $keyParams['object_name'];
|
||||
}
|
||||
$class = DbObjectTypeRegistry::classByType($activity->getObjectTable());
|
||||
$uuid = $activity->getObjectUuid();
|
||||
|
||||
$exists = $class::exists($keyParams, $this->connection);
|
||||
if ($modification->isCreation()) {
|
||||
$exists = $class::uniqueIdExists($uuid, $this->connection);
|
||||
if ($activity->isActionCreate()) {
|
||||
if ($exists) {
|
||||
if (! isset($this->ignoreUuids[$uuid->getBytes()])) {
|
||||
throw new MergeErrorRecreateOnMerge($modification, $uuid);
|
||||
if (! $this->ignoresActivity($activity)) {
|
||||
throw new MergeErrorRecreateOnMerge($activity);
|
||||
}
|
||||
} else {
|
||||
$object = IcingaObjectModification::applyModification($modification, null, $this->connection);
|
||||
$object->store($this->connection);
|
||||
$activity->createDbObject()->store($this->connection);
|
||||
}
|
||||
} elseif ($modification->isDeletion()) {
|
||||
} elseif ($activity->isActionDelete()) {
|
||||
if ($exists) {
|
||||
$object = IcingaObjectModification::applyModification($modification, $class::load($keyParams, $this->connection), $this->connection);
|
||||
$object->setConnection($this->connection);
|
||||
$object->delete();
|
||||
} elseif (! $this->ignoreDeleteWhenMissing && ! isset($this->ignoreUuids[$binaryUuid])) {
|
||||
throw new MergeErrorDeleteMissingObject($modification, $uuid);
|
||||
$activity->deleteDbObject($this->connection);
|
||||
} elseif (! $this->ignoreDeleteWhenMissing && ! $this->ignoresActivity($activity)) {
|
||||
throw new MergeErrorDeleteMissingObject($activity);
|
||||
}
|
||||
} else {
|
||||
if ($exists) {
|
||||
$object = IcingaObjectModification::applyModification($modification, $class::load($keyParams, $this->connection), $this->connection);
|
||||
// TODO: du änderst ein Objekt, und die geänderte Eigenschaften haben sich seit der Änderung geändert
|
||||
$object->store($this->connection);
|
||||
} elseif (! $this->ignoreModificationWhenMissing && ! isset($this->ignoreUuids[$binaryUuid])) {
|
||||
throw new MergeErrorModificationForMissingObject($modification, $uuid);
|
||||
$current = $class::requireWithUniqueId($uuid, $this->connection);
|
||||
$activity->applyToDbObject($class::requireWithUniqueId($uuid, $this->connection))->store();
|
||||
// TODO: you modified an object, and related properties have been changed in the meantime.
|
||||
// We're able to detect this with the given data, and might want to offer a rebase.
|
||||
} elseif (! $this->ignoreModificationWhenMissing && ! $this->ignoresActivity($activity)) {
|
||||
throw new MergeErrorModificationForMissingObject($activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,13 @@ class BranchModificationInspection
|
|||
{
|
||||
use TranslationHelper;
|
||||
|
||||
protected $connection;
|
||||
|
||||
protected $db;
|
||||
|
||||
public function __construct(Db $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->db = $connection->getDbAdapter();
|
||||
}
|
||||
|
||||
|
@ -74,10 +77,10 @@ class BranchModificationInspection
|
|||
public function loadSingleTableStats($table, UuidInterface $uuid)
|
||||
{
|
||||
$query = $this->db->select()->from($table, [
|
||||
'cnt_created' => "SUM(CASE WHEN created = 'y' THEN 1 ELSE 0 END)",
|
||||
'cnt_deleted' => "SUM(CASE WHEN deleted = 'y' THEN 1 ELSE 0 END)",
|
||||
'cnt_modified' => "SUM(CASE WHEN deleted = 'n' AND created = 'n' THEN 1 ELSE 0 END)",
|
||||
])->where('branch_uuid = ?', $uuid->getBytes());
|
||||
'cnt_created' => "SUM(CASE WHEN branch_created = 'y' THEN 1 ELSE 0 END)",
|
||||
'cnt_deleted' => "SUM(CASE WHEN branch_deleted = 'y' THEN 1 ELSE 0 END)",
|
||||
'cnt_modified' => "SUM(CASE WHEN branch_deleted = 'n' AND branch_created = 'n' THEN 1 ELSE 0 END)",
|
||||
])->where('branch_uuid = ?', $this->connection->quoteBinary($uuid->getBytes()));
|
||||
|
||||
return $this->db->fetchRow($query);
|
||||
}
|
||||
|
|
|
@ -1,267 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
|
||||
use Icinga\Module\Director\Data\Json;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class BranchModificationStore
|
||||
{
|
||||
// TODO: Ranges is weird. key = scheduled_downtime_id, range_type, range_key
|
||||
const ENCODED_ARRAYS = ['imports', 'groups', 'ranges'];
|
||||
|
||||
const ENCODED_DICTIONARIES = ['vars', 'arguments'];
|
||||
|
||||
protected $connection;
|
||||
|
||||
protected $db;
|
||||
|
||||
protected $shortType;
|
||||
|
||||
protected $table;
|
||||
|
||||
public function __construct(Db $connection, $shortType)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->shortType = $shortType;
|
||||
$this->table = "branched_icinga_$shortType";
|
||||
$this->db = $connection->getDbAdapter();
|
||||
}
|
||||
|
||||
public function loadAll(UuidInterface $branchUuid)
|
||||
{
|
||||
return $this->db->fetchAll($this->select()->where('branch_uuid = ?', $branchUuid->getBytes()));
|
||||
}
|
||||
|
||||
public function eventuallyLoadModification($objectId, UuidInterface $branchUuid)
|
||||
{
|
||||
if ($objectId) {
|
||||
$row = $this->fetchOptional($objectId, $branchUuid);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if ($row) {
|
||||
$id = (int) $objectId;
|
||||
$class = DbObjectTypeRegistry::classByType($this->shortType);
|
||||
if ($row->deleted === 'y') {
|
||||
return ObjectModification::delete($class, $id, static::cleanupRow($row));
|
||||
}
|
||||
if ($row->created === 'y') {
|
||||
return ObjectModification::create($class, $row->object_name, static::cleanupRow($row));
|
||||
}
|
||||
|
||||
// TODO: Former properties null? DB Problem.
|
||||
return ObjectModification::modify($class, $id, null, static::filterNull(static::cleanupRow($row)));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadOptionalModificationByName($objectName, UuidInterface $branchUuid)
|
||||
{
|
||||
$row = $this->fetchOptionalByName($objectName, $branchUuid);
|
||||
if ($row) {
|
||||
$class = DbObjectTypeRegistry::classByType($this->shortType);
|
||||
if ($row->created === 'y') {
|
||||
return ObjectModification::create($class, $row->object_name, static::cleanupRow($row));
|
||||
}
|
||||
if ($row->deleted === 'y') {
|
||||
throw new \RuntimeException('Delete for a probably non-existing object? Not sure');
|
||||
// return ObjectModification::delete($class, $row->object_name, ...);
|
||||
}
|
||||
|
||||
// Hint: this is not correct. Former properties are missing. We finish up here, when loading renamed objects.
|
||||
return ObjectModification::modify($class, $row->object_name, [], static::filterNull(static::cleanupRow($row)));
|
||||
|
||||
// TODO: better exception, handle this in the frontend
|
||||
//throw new \RuntimeException('Got a modification for a probably non-existing object');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function filterNull($row)
|
||||
{
|
||||
return (object) array_filter((array) $row, function ($value) {
|
||||
return $value !== null;
|
||||
});
|
||||
}
|
||||
|
||||
protected function cleanupRow($row)
|
||||
{
|
||||
unset($row->object_id, $row->class, $row->branch_uuid, $row->uuid, $row->created, $row->deleted);
|
||||
return $row;
|
||||
}
|
||||
|
||||
protected function fetchOptional($objectId, UuidInterface $branchUuid)
|
||||
{
|
||||
return $this->optionalRow($this->select()
|
||||
->where('object_id = ?', $objectId)
|
||||
->where('branch_uuid = ?', $branchUuid->getBytes()));
|
||||
}
|
||||
|
||||
protected function fetchOptionalByName($objectName, UuidInterface $branchUuid)
|
||||
{
|
||||
return $this->optionalRow($this->select()
|
||||
->where('object_name = ?', $objectName)
|
||||
->where('branch_uuid = ?', $branchUuid->getBytes()));
|
||||
}
|
||||
|
||||
protected function optionalRow($query)
|
||||
{
|
||||
if ($row = $this->db->fetchRow($query)) {
|
||||
$this->decodeEncodedProperties($row);
|
||||
return $row;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function select()
|
||||
{
|
||||
return $this->db->select()->from($this->table);
|
||||
}
|
||||
|
||||
protected function decodeEncodedProperties($row)
|
||||
{
|
||||
foreach (array_merge(self::ENCODED_ARRAYS, self::ENCODED_DICTIONARIES) as $encodedProperty) {
|
||||
// vars, imports and groups might be null or not set at all (if not supported)
|
||||
if (! empty($row->$encodedProperty)) {
|
||||
$row->$encodedProperty = Json::decode($row->$encodedProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareModificationForStore(ObjectModification $modification)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
|
||||
public function store(ObjectModification $modification, $objectId, UuidInterface $branchUuid)
|
||||
{
|
||||
if ($properties = $modification->getProperties()) {
|
||||
$properties = (array) $properties->jsonSerialize();
|
||||
} else {
|
||||
$properties = [];
|
||||
}
|
||||
|
||||
// Former properties are not needed, as they are dealt with in persistModification.
|
||||
if ($objectId) {
|
||||
$existing = $this->fetchOptional($objectId, $branchUuid);
|
||||
} else {
|
||||
$existing = null;
|
||||
}
|
||||
foreach (self::ENCODED_DICTIONARIES as $deepProperty) {
|
||||
if (isset($properties[$deepProperty])) {
|
||||
// TODO: flags
|
||||
$properties[$deepProperty] = Json::encode($properties[$deepProperty]);
|
||||
}
|
||||
}
|
||||
/* TODO: Nothing should be flat here, verify and remove this comment
|
||||
foreach (self::ENCODED_DICTIONARIES as $property) {
|
||||
$this->combineAndEncodeFlatDictionaries($properties, $existing, $property);
|
||||
}
|
||||
*/
|
||||
foreach (self::ENCODED_ARRAYS as $deepProperty) {
|
||||
if (isset($properties[$deepProperty])) {
|
||||
// TODO: flags
|
||||
$properties[$deepProperty] = Json::encode($properties[$deepProperty]);
|
||||
}
|
||||
}
|
||||
$this->connection->runFailSafeTransaction(function () use (
|
||||
$existing,
|
||||
$modification,
|
||||
$objectId,
|
||||
$branchUuid,
|
||||
$properties
|
||||
) {
|
||||
if ($existing) {
|
||||
if ($modification->isDeletion()) {
|
||||
$this->deleteExisting($existing->uuid);
|
||||
$this->delete($objectId, $branchUuid);
|
||||
} elseif ($existing->deleted === 'y') {
|
||||
$this->deleteExisting($existing->uuid);
|
||||
$this->create($objectId, $branchUuid, $properties);
|
||||
} else {
|
||||
$this->update($existing->uuid, $properties);
|
||||
}
|
||||
} else {
|
||||
if ($modification->isCreation()) {
|
||||
$this->create($objectId, $branchUuid, $properties);
|
||||
} elseif ($modification->isDeletion()) {
|
||||
$this->delete($objectId, $branchUuid);
|
||||
} else {
|
||||
$this->createModification($objectId, $branchUuid, $properties);
|
||||
}
|
||||
}
|
||||
$activities = new BranchActivityStore($this->connection);
|
||||
$activities->persistModification($modification, $branchUuid);
|
||||
});
|
||||
}
|
||||
|
||||
protected function combineAndEncodeFlatDictionaries(&$properties, $existing, $prefix)
|
||||
{
|
||||
if ($existing && ! empty($existing->$prefix)) {
|
||||
// $vars = (array) Json::decode($existing->vars);
|
||||
$vars = (array) ($existing->$prefix);
|
||||
} else {
|
||||
$vars = [];
|
||||
}
|
||||
$length = strlen($prefix) + 1;
|
||||
foreach ($properties as $key => $value) {
|
||||
if (substr($key, 0, $length) === "$prefix.") {
|
||||
$vars[substr($key, $length)] = $value;
|
||||
}
|
||||
}
|
||||
if (! empty($vars)) {
|
||||
foreach (array_keys($vars) as $key) {
|
||||
unset($properties["$prefix.$key"]);
|
||||
}
|
||||
$properties[$prefix] = Json::encode((object) $vars); // TODO: flags!
|
||||
}
|
||||
}
|
||||
|
||||
protected function deleteExisting($binaryUuid)
|
||||
{
|
||||
$this->db->delete($this->table, $this->db->quoteInto('uuid = ?', $binaryUuid));
|
||||
}
|
||||
|
||||
protected function create($objectId, UuidInterface $branchUuid, $properties)
|
||||
{
|
||||
$this->db->insert($this->table, [
|
||||
'branch_uuid' => $branchUuid->getBytes(),
|
||||
'uuid' => Uuid::uuid4()->getBytes(),
|
||||
'object_id' => $objectId,
|
||||
'created' => 'y',
|
||||
] + (array) $properties);
|
||||
}
|
||||
|
||||
protected function delete($objectId, UuidInterface $branchUuid)
|
||||
{
|
||||
$this->db->insert($this->table, [
|
||||
'branch_uuid' => $branchUuid->getBytes(),
|
||||
'uuid' => Uuid::uuid4()->getBytes(),
|
||||
'object_id' => $objectId,
|
||||
'deleted' => 'y',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function createModification($objectId, UuidInterface $branchUuid, $properties)
|
||||
{
|
||||
$this->db->insert($this->table, [
|
||||
'branch_uuid' => $branchUuid->getBytes(),
|
||||
'uuid' => Uuid::uuid4()->getBytes(),
|
||||
'object_id' => $objectId,
|
||||
] + (array) $properties);
|
||||
}
|
||||
|
||||
protected function update($binaryUuid, $properties)
|
||||
{
|
||||
$this->db->update($this->table, [
|
||||
'uuid' => Uuid::uuid4()->getBytes(),
|
||||
] + (array) $properties, $this->db->quoteInto('uuid = ?', $binaryUuid));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Module\Director\Data\Json;
|
||||
use function in_array;
|
||||
|
||||
/**
|
||||
* Hardcoded branch-related settings
|
||||
*/
|
||||
class BranchSettings
|
||||
{
|
||||
// TODO: Ranges is weird. key = scheduled_downtime_id, range_type, range_key
|
||||
const ENCODED_ARRAYS = ['imports', 'groups', 'ranges', 'users', 'usergroups'];
|
||||
|
||||
const ENCODED_DICTIONARIES = ['vars', 'arguments'];
|
||||
|
||||
const BRANCH_SPECIFIC_PROPERTIES = [
|
||||
'uuid',
|
||||
'branch_uuid',
|
||||
'branch_created',
|
||||
'branch_deleted',
|
||||
'set_null',
|
||||
];
|
||||
|
||||
const BRANCH_BOOLEANS = [
|
||||
'branch_created',
|
||||
'branch_deleted',
|
||||
];
|
||||
|
||||
const RELATED_SETS = [
|
||||
'types',
|
||||
'states',
|
||||
];
|
||||
|
||||
public static function propertyIsEncodedArray($property)
|
||||
{
|
||||
return in_array($property, self::ENCODED_ARRAYS, true);
|
||||
}
|
||||
|
||||
public static function propertyIsRelatedSet($property)
|
||||
{
|
||||
// TODO: get from object class
|
||||
return in_array($property, self::RELATED_SETS, true);
|
||||
}
|
||||
|
||||
public static function propertyIsEncodedDictionary($property)
|
||||
{
|
||||
return in_array($property, self::ENCODED_DICTIONARIES, true);
|
||||
}
|
||||
|
||||
public static function propertyIsBranchSpecific($property)
|
||||
{
|
||||
return in_array($property, self::BRANCH_SPECIFIC_PROPERTIES, true);
|
||||
}
|
||||
|
||||
public static function flattenEncodedDicationaries(array &$properties)
|
||||
{
|
||||
foreach (self::ENCODED_DICTIONARIES as $property) {
|
||||
self::flattenProperty($properties, $property);
|
||||
}
|
||||
}
|
||||
|
||||
public static function normalizeBranchedObjectFromDb($row)
|
||||
{
|
||||
$normalized = [];
|
||||
$row = (array) $row;
|
||||
foreach ($row as $key => $value) {
|
||||
if (! static::propertyIsBranchSpecific($key)) {
|
||||
if (is_resource($value)) {
|
||||
$value = stream_get_contents($value);
|
||||
}
|
||||
if ($value !== null && static::propertyIsEncodedArray($key)) {
|
||||
$value = Json::decode($value);
|
||||
}
|
||||
if ($value !== null && static::propertyIsRelatedSet($key)) {
|
||||
// TODO: We might want to combine them (current VS branched)
|
||||
$value = Json::decode($value);
|
||||
}
|
||||
if ($value !== null && static::propertyIsEncodedDictionary($key)) {
|
||||
$value = Json::decode($value);
|
||||
}
|
||||
if ($value !== null) {
|
||||
$normalized[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
static::flattenEncodedDicationaries($row);
|
||||
if (isset($row['set_null'])) {
|
||||
foreach (Json::decode($row['set_null']) as $property) {
|
||||
$normalized[$property] = null;
|
||||
}
|
||||
}
|
||||
foreach (self::BRANCH_BOOLEANS as $key) {
|
||||
if ($row[$key] === 'y') {
|
||||
$row[$key] = true;
|
||||
} elseif ($row[$key] === 'n') {
|
||||
$row[$key] = false;
|
||||
} else {
|
||||
throw new \RuntimeException(sprintf(
|
||||
"Boolean DB property expected, got '%s' for '%s'",
|
||||
$row[$key],
|
||||
$key
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
public static function flattenProperty(array &$properties, $property)
|
||||
{
|
||||
// TODO: dots in varnames -> throw or escape?
|
||||
if (isset($properties[$property])) {
|
||||
foreach ((array) $properties[$property] as $key => $value) {
|
||||
$properties["$property.$key"] = $value;
|
||||
}
|
||||
unset($properties[$property]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,9 @@ class BranchStore
|
|||
protected function newFromDbResult($query)
|
||||
{
|
||||
if ($row = $this->db->fetchRow($query)) {
|
||||
if (is_resource($row->uuid)) {
|
||||
$row->uuid = stream_get_contents($row->uuid);
|
||||
}
|
||||
return Branch::fromDbRow($row);
|
||||
}
|
||||
|
||||
|
@ -52,7 +55,7 @@ class BranchStore
|
|||
public function setReadyForMerge(Branch $branch)
|
||||
{
|
||||
$update = [
|
||||
'should_be_merged' => 'y'
|
||||
'ts_merge_request' => (int) floor(microtime(true) * 1000000)
|
||||
];
|
||||
|
||||
$name = $branch->getName();
|
||||
|
@ -72,8 +75,8 @@ class BranchStore
|
|||
'owner' => 'b.owner',
|
||||
'branch_name' => 'b.branch_name',
|
||||
'description' => 'b.description',
|
||||
'should_be_merged' => 'b.should_be_merged',
|
||||
'cnt_activities' => 'COUNT(ba.change_time)',
|
||||
'ts_merge_request' => 'b.ts_merge_request',
|
||||
'cnt_activities' => 'COUNT(ba.timestamp_ns)',
|
||||
])->joinLeft(
|
||||
['ba' => 'director_branch_activity'],
|
||||
'b.uuid = ba.branch_uuid',
|
||||
|
@ -103,16 +106,36 @@ class BranchStore
|
|||
*/
|
||||
public function createBranchByName($branchName, $owner)
|
||||
{
|
||||
$this->uuid = Uuid::uuid4();
|
||||
$uuid = Uuid::uuid4();
|
||||
$properties = [
|
||||
'uuid' => $this->uuid->getBytes(),
|
||||
'uuid' => $this->connection->quoteBinary($uuid->getBytes()),
|
||||
'branch_name' => $branchName,
|
||||
'owner' => $owner,
|
||||
'description' => null,
|
||||
'should_be_merged' => 'n',
|
||||
'ts_merge_request' => null,
|
||||
];
|
||||
$this->db->insert($this->table, $properties);
|
||||
|
||||
return Branch::fromDbRow((object) $properties);
|
||||
if ($branch = static::fetchBranchByUuid($uuid)) {
|
||||
return $branch;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Branch with UUID=%s has been created, but could not be fetched from DB',
|
||||
$uuid->toString()
|
||||
));
|
||||
}
|
||||
|
||||
public function deleteByUuid(UuidInterface $uuid)
|
||||
{
|
||||
return $this->db->delete($this->table, $this->db->quoteInto(
|
||||
'uuid = ?',
|
||||
$this->connection->quoteBinary($uuid->getBytes())
|
||||
));
|
||||
}
|
||||
|
||||
public function delete(Branch $branch)
|
||||
{
|
||||
return $this->deleteByUuid($branch->getUuid());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,387 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
|
||||
use Icinga\Module\Director\Data\Json;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use stdClass;
|
||||
|
||||
class BranchedObject
|
||||
{
|
||||
/** @var UuidInterface */
|
||||
protected $branchUuid;
|
||||
|
||||
/** @var ?DbObject */
|
||||
protected $object;
|
||||
|
||||
/** @var ?stdClass */
|
||||
protected $changes;
|
||||
|
||||
/** @var bool */
|
||||
protected $branchDeleted;
|
||||
|
||||
/** @var bool */
|
||||
protected $branchCreated;
|
||||
|
||||
/** @var UuidInterface */
|
||||
private $objectUuid;
|
||||
|
||||
/** @var string */
|
||||
private $objectTable;
|
||||
|
||||
/** @var bool */
|
||||
private $loadedAsBranchedObject = false;
|
||||
|
||||
/**
|
||||
* @param BranchActivity $activity
|
||||
* @param Db $connection
|
||||
* @return static
|
||||
*/
|
||||
public static function withActivity(BranchActivity $activity, Db $connection)
|
||||
{
|
||||
return self::loadOptional(
|
||||
$connection,
|
||||
$activity->getObjectTable(),
|
||||
$activity->getObjectUuid(),
|
||||
$activity->getBranchUuid()
|
||||
)->applyActivity($activity, $connection);
|
||||
}
|
||||
|
||||
public function store(Db $connection)
|
||||
{
|
||||
if ($this->object && ! $this->object->hasBeenModified() && empty($this->changes)) {
|
||||
return false;
|
||||
}
|
||||
$db = $connection->getDbAdapter();
|
||||
|
||||
$properties = [
|
||||
'branch_deleted' => $this->branchDeleted ? 'y' : 'n',
|
||||
'branch_created' => $this->branchCreated ? 'y' : 'n',
|
||||
] + $this->prepareChangedProperties();
|
||||
|
||||
$table = 'branched_' . $this->objectTable;
|
||||
if ($this->loadedAsBranchedObject) {
|
||||
return $db->update(
|
||||
$table,
|
||||
$properties,
|
||||
$this->prepareWhereString($connection)
|
||||
) === 1;
|
||||
} else {
|
||||
try {
|
||||
return $db->insert($table, $this->prepareKeyProperties($connection) + $properties) === 1;
|
||||
} catch (\Exception $e) {
|
||||
var_dump($e->getMessage());
|
||||
var_dump($this->prepareKeyProperties($connection) + $properties);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(Db $connection)
|
||||
{
|
||||
$db = $connection->getDbAdapter();
|
||||
$table = 'branched_' . $this->objectTable;
|
||||
$branchCreated = $db->fetchOne($this->filterQuery($db->select()->from($table, 'branch_created'), $connection));
|
||||
// We do not want to nullify all properties, therefore: delete & insert
|
||||
$db->delete($table, $this->prepareWhereString($connection));
|
||||
|
||||
if (! $branchCreated) {
|
||||
// No need to insert a deleted object in case this object lived in this branch only
|
||||
return $db->insert($table, $this->prepareKeyProperties($connection) + [
|
||||
'branch_deleted' => 'y',
|
||||
'branch_created' => 'n',
|
||||
]) === 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function prepareKeyProperties(Db $connection)
|
||||
{
|
||||
return [
|
||||
'uuid' => $connection->quoteBinary($this->objectUuid->getBytes()),
|
||||
'branch_uuid' => $connection->quoteBinary($this->branchUuid->getBytes()),
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareWhereString(Db $connection)
|
||||
{
|
||||
$db = $connection->getDbAdapter();
|
||||
$objectUuid = $connection->quoteBinary($this->objectUuid->getBytes());
|
||||
$branchUuid = $connection->quoteBinary($this->branchUuid->getBytes());
|
||||
|
||||
return $db->quoteInto('uuid = ?', $objectUuid) . $db->quoteInto(' AND branch_uuid = ?', $branchUuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend_Db_Select $query
|
||||
* @param Db $connection
|
||||
* @return \Zend_Db_Select
|
||||
*/
|
||||
protected function filterQuery(\Zend_Db_Select $query, Db $connection)
|
||||
{
|
||||
return $query->where('uuid = ?', $connection->quoteBinary($this->objectUuid->getBytes()))
|
||||
->where('branch_uuid = ?', $connection->quoteBinary($this->branchUuid->getBytes()));
|
||||
}
|
||||
|
||||
protected function prepareChangedProperties()
|
||||
{
|
||||
$properties = (array) $this->changes;
|
||||
|
||||
foreach (BranchSettings::ENCODED_DICTIONARIES as $property) {
|
||||
$this->combineFlatDictionaries($properties, $property);
|
||||
}
|
||||
foreach (BranchSettings::ENCODED_DICTIONARIES as $property) {
|
||||
if (isset($properties[$property])) {
|
||||
$properties[$property] = Json::encode($properties[$property]);
|
||||
}
|
||||
}
|
||||
foreach (BranchSettings::ENCODED_ARRAYS as $property) {
|
||||
if (isset($properties[$property])) {
|
||||
$properties[$property] = Json::encode($properties[$property]);
|
||||
}
|
||||
}
|
||||
foreach (BranchSettings::RELATED_SETS as $property) {
|
||||
if (isset($properties[$property])) {
|
||||
$properties[$property] = Json::encode($properties[$property]);
|
||||
}
|
||||
}
|
||||
$setNull = [];
|
||||
if (array_key_exists('disabled', $properties) && $properties['disabled'] === null) {
|
||||
unset($properties['disabled']);
|
||||
}
|
||||
foreach ($properties as $key => $value) {
|
||||
if ($value === null) {
|
||||
$setNull[] = $key;
|
||||
}
|
||||
}
|
||||
if (empty($setNull)) {
|
||||
$properties['set_null'] = null;
|
||||
} else {
|
||||
$properties['set_null'] = Json::encode($setNull);
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
protected function combineFlatDictionaries(&$properties, $prefix)
|
||||
{
|
||||
$vars = [];
|
||||
$length = strlen($prefix) + 1;
|
||||
foreach ($properties as $key => $value) {
|
||||
if (substr($key, 0, $length) === "$prefix.") {
|
||||
$vars[substr($key, $length)] = $value;
|
||||
}
|
||||
}
|
||||
if (! empty($vars)) {
|
||||
foreach (array_keys($vars) as $key) {
|
||||
unset($properties["$prefix.$key"]);
|
||||
}
|
||||
$properties[$prefix] = (object) $vars;
|
||||
}
|
||||
}
|
||||
|
||||
public function applyActivity(BranchActivity $activity, Db $connection)
|
||||
{
|
||||
if ($activity->isActionDelete()) {
|
||||
throw new \RuntimeException('Cannot apply a delete action');
|
||||
}
|
||||
if ($activity->isActionCreate()) {
|
||||
if ($this->hasBeenTouchedByBranch()) {
|
||||
throw new \RuntimeException('Cannot apply a CREATE activity to an already branched object');
|
||||
} else {
|
||||
$this->branchCreated = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($activity->getModifiedProperties()->jsonSerialize() as $key => $value) {
|
||||
$this->changes[$key] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Db $connection
|
||||
* @param string $objectTable
|
||||
* @param UuidInterface $uuid
|
||||
* @param Branch $branch
|
||||
* @return static
|
||||
* @throws NotFoundError
|
||||
*/
|
||||
public static function load(Db $connection, $objectTable, UuidInterface $uuid, Branch $branch)
|
||||
{
|
||||
$object = static::loadOptional($connection, $objectTable, $uuid, $branch->getUuid());
|
||||
if ($object->getOriginalDbObject() === null && ! $object->hasBeenTouchedByBranch()) {
|
||||
throw new NotFoundError('Not found');
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBeenTouchedByBranch()
|
||||
{
|
||||
return $this->loadedAsBranchedObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBeenDeletedByBranch()
|
||||
{
|
||||
return $this->branchDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBeenCreatedByBranch()
|
||||
{
|
||||
return $this->branchCreated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?DbObject
|
||||
*/
|
||||
public function getOriginalDbObject()
|
||||
{
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?DbObject
|
||||
*/
|
||||
public function getBranchedDbObject(Db $connection)
|
||||
{
|
||||
if ($this->object) {
|
||||
$branched = DbObjectTypeRegistry::newObject($this->objectTable, [], $connection);
|
||||
// object_type first, to avoid:
|
||||
// I can only assign for applied objects or objects with native support for assignments
|
||||
if ($this->object->hasProperty('object_type')) {
|
||||
$branched->set('object_type', $this->object->get('object_type'));
|
||||
}
|
||||
foreach ((array) $this->object->toPlainObject(false, true) as $key => $value) {
|
||||
if ($key === 'object_type') {
|
||||
continue;
|
||||
}
|
||||
$branched->set($key, $value);
|
||||
}
|
||||
$branched->set('id', $this->object->get('id'));
|
||||
$branched->set('uuid', $this->object->get('uuid'));
|
||||
} else {
|
||||
$branched = DbObjectTypeRegistry::newObject($this->objectTable, [], $connection);
|
||||
$branched->setUniqueId($this->objectUuid);
|
||||
}
|
||||
if ($this->changes === null) {
|
||||
return $branched;
|
||||
}
|
||||
foreach ($this->changes as $key => $value) {
|
||||
if ($key === 'set_null') {
|
||||
if ($value !== null) {
|
||||
foreach ($value as $k) {
|
||||
$branched->set($k, null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$branched->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $branched;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UuidInterface
|
||||
*/
|
||||
public function getBranchUuid()
|
||||
{
|
||||
return $this->branchUuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Db $connection
|
||||
* @param string $table
|
||||
* @param UuidInterface $uuid
|
||||
* @param ?UuidInterface $branchUuid
|
||||
* @return static
|
||||
*/
|
||||
protected static function loadOptional(
|
||||
Db $connection,
|
||||
$table,
|
||||
UuidInterface $uuid,
|
||||
UuidInterface $branchUuid = null
|
||||
) {
|
||||
$class = DbObjectTypeRegistry::classByType($table);
|
||||
if ($row = static::optionalTableRowByUuid($connection, $table, $uuid)) {
|
||||
$object = $class::fromDbRow((array) $row, $connection);
|
||||
} else {
|
||||
$object = null;
|
||||
}
|
||||
|
||||
$self = new static();
|
||||
$self->object = $object;
|
||||
$self->objectUuid = $uuid;
|
||||
$self->branchUuid = $branchUuid;
|
||||
$self->objectTable = $table;
|
||||
|
||||
if ($branchUuid && $row = static::optionalBranchedTableRowByUuid($connection, $table, $uuid, $branchUuid)) {
|
||||
if ($row->branch_deleted === 'y') {
|
||||
$self->branchDeleted = true;
|
||||
} elseif ($row->branch_created === 'y') {
|
||||
$self->branchCreated = true;
|
||||
}
|
||||
$self->changes = BranchSettings::normalizeBranchedObjectFromDb($row);
|
||||
$self->loadedAsBranchedObject = true;
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Db $connection
|
||||
* @param string $table
|
||||
* @param UuidInterface $uuid
|
||||
* @return stdClass|boolean
|
||||
*/
|
||||
protected static function optionalTableRowByUuid(Db $connection, $table, UuidInterface $uuid)
|
||||
{
|
||||
$db = $connection->getDbAdapter();
|
||||
|
||||
return $db->fetchRow(
|
||||
$db->select()->from($table)->where('uuid = ?', $connection->quoteBinary($uuid->getBytes()))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Db $connection
|
||||
* @param string $table
|
||||
* @param UuidInterface $uuid
|
||||
* @return stdClass|boolean
|
||||
*/
|
||||
protected static function optionalBranchedTableRowByUuid(
|
||||
Db $connection,
|
||||
$table,
|
||||
UuidInterface $uuid,
|
||||
UuidInterface $branchUuid
|
||||
) {
|
||||
$db = $connection->getDbAdapter();
|
||||
|
||||
$query = $db->select()
|
||||
->from("branched_$table")
|
||||
->where('uuid = ?', $connection->quoteBinary($uuid->getBytes()))
|
||||
->where('branch_uuid = ?', $connection->quoteBinary($branchUuid->getBytes()));
|
||||
|
||||
return $db->fetchRow($query);
|
||||
}
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
|
||||
class IcingaObjectModification
|
||||
{
|
||||
/**
|
||||
* @param DbObject $object
|
||||
* @return ObjectModification
|
||||
*/
|
||||
public static function getModification(DbObject $object)
|
||||
{
|
||||
if ($object->shouldBeRemoved()) {
|
||||
return static::delete($object);
|
||||
}
|
||||
|
||||
if ($object->hasBeenLoadedFromDb()) {
|
||||
return static::modify($object);
|
||||
}
|
||||
|
||||
return static::create($object);
|
||||
}
|
||||
|
||||
protected static function fixForeignKeys($object)
|
||||
{
|
||||
// TODO: Generic, _name?? Lookup?
|
||||
$keys = [
|
||||
'check_command_name',
|
||||
'check_period_name',
|
||||
'event_command_name',
|
||||
'command_endpoint_name',
|
||||
'zone_name',
|
||||
'host_name',
|
||||
];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (property_exists($object, $key)) {
|
||||
$object->{substr($key, 0, -5)} = $object->$key;
|
||||
unset($object->$key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function applyModification(ObjectModification $modification, DbObject $object = null, Db $db = null)
|
||||
{
|
||||
if ($modification->isDeletion()) {
|
||||
$object->markForRemoval();
|
||||
} elseif ($modification->isCreation()) {
|
||||
/** @var string|DbObject $class */
|
||||
$class = $modification->getClassName();
|
||||
$properties = $modification->getProperties()->jsonSerialize();
|
||||
self::fixForeignKeys($properties);
|
||||
$object = $class::create((array) $properties, $db);
|
||||
} else {
|
||||
// TODO: Add "reset Properties", those that have been nulled
|
||||
$properties = (array) $modification->getProperties()->jsonSerialize();
|
||||
foreach (BranchModificationStore::ENCODED_DICTIONARIES as $property) {
|
||||
self::flattenProperty($properties, $property);
|
||||
}
|
||||
if ($object === null) {
|
||||
echo '<pre>';
|
||||
debug_print_backtrace();
|
||||
echo '</pre>';
|
||||
exit;
|
||||
}
|
||||
foreach ($properties as $key => $value) {
|
||||
$object->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Just to be on the safe side
|
||||
if ($db) {
|
||||
$object->setConnection($db);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
public static function delete(DbObject $object)
|
||||
{
|
||||
return ObjectModification::delete(
|
||||
get_class($object),
|
||||
self::getKey($object),
|
||||
$object->toPlainObject(false, true)
|
||||
);
|
||||
}
|
||||
|
||||
public static function create(DbObject $object)
|
||||
{
|
||||
return ObjectModification::create(
|
||||
get_class($object),
|
||||
self::getKey($object),
|
||||
$object->toPlainObject(false, true)
|
||||
);
|
||||
}
|
||||
|
||||
protected static function getKey(DbObject $object)
|
||||
{
|
||||
return $object->getKeyParams();
|
||||
}
|
||||
|
||||
protected static function flattenProperty(array &$properties, $property)
|
||||
{
|
||||
// TODO: dots in varnames -> throw or escape?
|
||||
if (isset($properties[$property])) {
|
||||
foreach ((array) $properties[$property] as $key => $value) {
|
||||
$properties["$property.$key"] = $value;
|
||||
}
|
||||
unset($properties[$property]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function modify(DbObject $object)
|
||||
{
|
||||
if (! $object instanceof IcingaObject) {
|
||||
throw new ProgrammingError('Plain object helpers for DbObject must be implemented');
|
||||
}
|
||||
$old = (array) $object->getPlainUnmodifiedObject();
|
||||
$new = (array) $object->toPlainObject(false, true);
|
||||
$unchangedKeys = [];
|
||||
foreach (BranchModificationStore::ENCODED_DICTIONARIES as $property) {
|
||||
self::flattenProperty($old, $property);
|
||||
self::flattenProperty($new, $property);
|
||||
}
|
||||
foreach ($old as $key => $value) {
|
||||
if (array_key_exists($key, $new) && $value === $new[$key]) {
|
||||
$unchangedKeys[] = $key;
|
||||
}
|
||||
}
|
||||
foreach ($unchangedKeys as $key) {
|
||||
unset($old[$key]);
|
||||
unset($new[$key]);
|
||||
}
|
||||
|
||||
return ObjectModification::modify(get_class($object), self::getKey($object), $old, $new);
|
||||
}
|
||||
}
|
|
@ -4,24 +4,17 @@ namespace Icinga\Module\Director\Db\Branch;
|
|||
|
||||
use Exception;
|
||||
use gipfl\Translation\TranslationHelper;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
abstract class MergeError extends Exception
|
||||
{
|
||||
use TranslationHelper;
|
||||
|
||||
/** @var ObjectModification */
|
||||
protected $modification;
|
||||
/** @var BranchActivity */
|
||||
protected $activity;
|
||||
|
||||
/** @var UuidInterface */
|
||||
protected $activityUuid;
|
||||
|
||||
public function __construct(ObjectModification $modification, UuidInterface $activityUuid)
|
||||
public function __construct(BranchActivity $activity)
|
||||
{
|
||||
$this->modification = $modification;
|
||||
$this->activityUuid = $activityUuid;
|
||||
$this->activity = $activity;
|
||||
parent::__construct($this->prepareMessage());
|
||||
}
|
||||
|
||||
|
@ -29,33 +22,16 @@ abstract class MergeError extends Exception
|
|||
|
||||
public function getObjectTypeName()
|
||||
{
|
||||
/** @var string|DbObject $class */
|
||||
$class = $this->getModification()->getClassName();
|
||||
$dummy = $class::create([]);
|
||||
if ($dummy instanceof IcingaObject) {
|
||||
return $dummy->getShortTableName();
|
||||
}
|
||||
|
||||
return $dummy->getTableName();
|
||||
}
|
||||
|
||||
public function getActivityUuid()
|
||||
{
|
||||
return $this->activityUuid;
|
||||
return preg_replace('/^icinga_/', '', $this->getActivity()->getObjectTable());
|
||||
}
|
||||
|
||||
public function getNiceObjectName()
|
||||
{
|
||||
$keyParams = $this->getModification()->getKeyParams();
|
||||
if (array_keys((array) $keyParams) === ['object_name']) {
|
||||
return $keyParams->object_name;
|
||||
}
|
||||
|
||||
return json_encode($keyParams);
|
||||
return $this->activity->getObjectName();
|
||||
}
|
||||
|
||||
public function getModification()
|
||||
public function getActivity()
|
||||
{
|
||||
return $this->modification;
|
||||
return $this->activity;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Module\Director\Data\DataArrayHelper;
|
||||
use Icinga\Module\Director\Data\Serializable;
|
||||
use Icinga\Module\Director\Data\SerializableValue;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class ObjectModification implements Serializable
|
||||
{
|
||||
const ACTION_CREATE = 'create';
|
||||
const ACTION_MODIFY = 'modify';
|
||||
const ACTION_DELETE = 'delete';
|
||||
|
||||
protected static $serializationProperties = [
|
||||
'class',
|
||||
'key',
|
||||
'action',
|
||||
'properties',
|
||||
'formerProperties',
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
protected $class;
|
||||
|
||||
/** @var \stdClass */
|
||||
protected $key;
|
||||
|
||||
/** @var string */
|
||||
protected $action;
|
||||
|
||||
/** @var SerializableValue|null */
|
||||
protected $properties;
|
||||
|
||||
/** @var SerializableValue|null */
|
||||
protected $formerProperties;
|
||||
|
||||
public function __construct(
|
||||
$class,
|
||||
$key,
|
||||
$action,
|
||||
SerializableValue $properties = null,
|
||||
SerializableValue $formerProperties = null
|
||||
) {
|
||||
$this->class = $class;
|
||||
$this->key = $key;
|
||||
$this->assertValidAction($action);
|
||||
$this->action = $action;
|
||||
$this->properties = $properties;
|
||||
$this->formerProperties = $formerProperties;
|
||||
}
|
||||
|
||||
public static function delete($class, $key, $formerProperties)
|
||||
{
|
||||
return new static(
|
||||
$class,
|
||||
$key,
|
||||
self::ACTION_DELETE,
|
||||
null,
|
||||
SerializableValue::wantSerializable($formerProperties)
|
||||
);
|
||||
}
|
||||
|
||||
public static function create($class, $key, $properties)
|
||||
{
|
||||
return new static($class, $key, self::ACTION_CREATE, SerializableValue::wantSerializable($properties));
|
||||
}
|
||||
|
||||
public static function modify($class, $key, $formerProperties, $properties)
|
||||
{
|
||||
return new static(
|
||||
$class,
|
||||
$key,
|
||||
self::ACTION_MODIFY,
|
||||
SerializableValue::wantSerializable($properties),
|
||||
SerializableValue::wantSerializable($formerProperties)
|
||||
);
|
||||
}
|
||||
|
||||
protected function assertValidAction($action)
|
||||
{
|
||||
if ($action !== self::ACTION_MODIFY
|
||||
&& $action !== self::ACTION_CREATE
|
||||
&& $action !== self::ACTION_DELETE
|
||||
) {
|
||||
throw new InvalidArgumentException("Valid action expected, got $action");
|
||||
}
|
||||
}
|
||||
|
||||
public function isDeletion()
|
||||
{
|
||||
return $this->action === self::ACTION_DELETE;
|
||||
}
|
||||
|
||||
public function isCreation()
|
||||
{
|
||||
return $this->action === self::ACTION_CREATE;
|
||||
}
|
||||
|
||||
public function isModification()
|
||||
{
|
||||
return $this->action === self::ACTION_MODIFY;
|
||||
}
|
||||
|
||||
public function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return (object) [
|
||||
'class' => $this->class,
|
||||
'key' => $this->key,
|
||||
'action' => $this->action,
|
||||
'properties' => $this->properties,
|
||||
'formerProperties' => $this->formerProperties,
|
||||
];
|
||||
}
|
||||
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
public function getFormerProperties()
|
||||
{
|
||||
return $this->formerProperties;
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function getKeyParams()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public static function fromSerialization($value)
|
||||
{
|
||||
$value = DataArrayHelper::wantArray($value);
|
||||
DataArrayHelper::failOnUnknownProperties($value, self::$serializationProperties);
|
||||
DataArrayHelper::requireProperties($value, ['class', 'key', 'action']);
|
||||
|
||||
return new static(
|
||||
$value['class'],
|
||||
$value['key'],
|
||||
$value['action'],
|
||||
isset($value['properties']) ? SerializableValue::fromSerialization($value['properties']) : null,
|
||||
isset($value['formerProperties']) ? SerializableValue::fromSerialization($value['formerProperties']) : null
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
class PlainObjectPropertyDiff
|
||||
{
|
||||
public static function calculate(array $old = null, array $new = null)
|
||||
{
|
||||
if ($new === null) {
|
||||
throw new \RuntimeException('Cannot diff for delete');
|
||||
}
|
||||
if ($old === null) {
|
||||
foreach (BranchSettings::ENCODED_DICTIONARIES as $property) {
|
||||
self::flattenProperty($new, $property);
|
||||
}
|
||||
|
||||
return $new;
|
||||
}
|
||||
$unchangedKeys = [];
|
||||
foreach (BranchSettings::ENCODED_DICTIONARIES as $property) {
|
||||
self::flattenProperty($old, $property);
|
||||
self::flattenProperty($new, $property);
|
||||
}
|
||||
foreach ($old as $key => $value) {
|
||||
if (array_key_exists($key, $new)) {
|
||||
if ($value === $new[$key]) {
|
||||
$unchangedKeys[] = $key;
|
||||
}
|
||||
} else {
|
||||
$new[$key] = null;
|
||||
}
|
||||
}
|
||||
foreach ($unchangedKeys as $key) {
|
||||
unset($new[$key]);
|
||||
}
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
protected static function flattenProperty(array &$properties, $property)
|
||||
{
|
||||
// TODO: dots in varnames -> throw or escape?
|
||||
if (isset($properties[$property])) {
|
||||
foreach ((array) $properties[$property] as $key => $value) {
|
||||
$properties["$property.$key"] = $value;
|
||||
}
|
||||
unset($properties[$property]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Db\Branch;
|
||||
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use RuntimeException;
|
||||
use function is_int;
|
||||
use function is_resource;
|
||||
use function is_string;
|
||||
|
||||
class UuidLookup
|
||||
{
|
||||
/**
|
||||
* @param Db $connection
|
||||
* @param Branch $branch
|
||||
* @param string $objectType
|
||||
* @param int|string $key
|
||||
* @param IcingaHost|null $host
|
||||
* @param IcingaServiceSet $set
|
||||
*/
|
||||
public static function findServiceUuid(
|
||||
Db $connection,
|
||||
Branch $branch,
|
||||
$objectType,
|
||||
$key = null,
|
||||
IcingaHost $host = null,
|
||||
IcingaServiceSet $set = null
|
||||
) {
|
||||
$db = $connection->getDbAdapter();
|
||||
$query = $db->select()->from('icinga_service', 'uuid')->where('object_type = ?', $objectType);
|
||||
$query = self::addKeyToQuery($query, $key);
|
||||
if ($host) {
|
||||
$query->add('host_id = ?', $host->get('id'));
|
||||
}
|
||||
if ($set) {
|
||||
$query->add('service_set_id = ?', $set->get('id'));
|
||||
}
|
||||
$uuid = self::fetchOptionalUuid($connection, $query);
|
||||
|
||||
if ($uuid === null && $branch->isBranch()) {
|
||||
// TODO: use different tables?
|
||||
$query = $db->select()->from('branched_icinga_service', 'uuid')->where('object_type = ?', $objectType);
|
||||
$query = self::addKeyToQuery($query, $key);
|
||||
if ($host) {
|
||||
// TODO: uuid?
|
||||
$query->add('host = ?', $host->getObjectName());
|
||||
}
|
||||
if ($set) {
|
||||
$query->add('service_set = ?', $set->getObjectName());
|
||||
}
|
||||
$uuid = self::fetchOptionalUuid($connection, $query);
|
||||
}
|
||||
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
public static function findUuidForKey($key, $table, Db $connection, Branch $branch)
|
||||
{
|
||||
$db = $connection->getDbAdapter();
|
||||
$query = self::addKeyToQuery($db->select()->from($table, 'uuid'), $key);
|
||||
$uuid = self::fetchOptionalUuid($connection, $query);
|
||||
if ($uuid === null && $branch->isBranch()) {
|
||||
$query = $db->select()->from("branched_$table", 'uuid')->where('object_name = ?', $key);
|
||||
$uuid = self::fetchOptionalUuid($connection, $query);
|
||||
}
|
||||
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
protected static function addKeyToQuery($query, $key)
|
||||
{
|
||||
if (is_int($key)) {
|
||||
$query->where('id = ?', $key);
|
||||
} elseif (is_string($key)) {
|
||||
$query->where('object_name = ?', $key);
|
||||
} else {
|
||||
throw new RuntimeException('Cannot deal with non-int/string keys for UUID fallback');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected static function fetchOptionalUuid(Db $connection, $query)
|
||||
{
|
||||
$result = $connection->getDbAdapter()->fetchOne($query);
|
||||
if (is_resource($result)) {
|
||||
$result = stream_get_contents($result);
|
||||
}
|
||||
if (is_string($result)) {
|
||||
return Uuid::fromBytes($result);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ namespace Icinga\Module\Director\Hook;
|
|||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Db\Branch\BranchSTore;
|
||||
|
@ -29,15 +28,6 @@ abstract class BranchSupportHook
|
|||
*/
|
||||
abstract public function linkToBranch(Branch $branch, Auth $auth, $label = null);
|
||||
|
||||
/**
|
||||
* @param string $label
|
||||
* @param Branch $branch
|
||||
* @param DbObject $object
|
||||
* @param Auth $auth
|
||||
* @return ?ValidHtml
|
||||
*/
|
||||
abstract public function linkToBranchedObject($label, Branch $branch, DbObject $object, Auth $auth);
|
||||
|
||||
/**
|
||||
* @param Db $db
|
||||
* @return Dashlet[]
|
||||
|
|
|
@ -288,8 +288,6 @@ class ExtensibleSet
|
|||
array_merge($props, array('property' => $value))
|
||||
);
|
||||
}
|
||||
|
||||
$this->fromDb['override'] = $this->ownValues;
|
||||
}
|
||||
|
||||
if (! empty($this->plusValues)) {
|
||||
|
@ -300,8 +298,6 @@ class ExtensibleSet
|
|||
array_merge($props, array('property' => $value))
|
||||
);
|
||||
}
|
||||
|
||||
$this->fromDb['extend'] = $this->ownValues;
|
||||
}
|
||||
|
||||
if (! empty($this->minusValues)) {
|
||||
|
@ -312,9 +308,18 @@ class ExtensibleSet
|
|||
array_merge($props, array('property' => $value))
|
||||
);
|
||||
}
|
||||
|
||||
$this->fromDb['blacklist'] = $this->ownValues;
|
||||
}
|
||||
|
||||
$this->setBeingLoadedFromDb();
|
||||
}
|
||||
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
$this->fromDb = [
|
||||
'override' => $this->ownValues ?: [],
|
||||
'extend' => $this->plusValues ?: [],
|
||||
'blacklist' => $this->minusValues ?: [],
|
||||
];
|
||||
}
|
||||
|
||||
public function override($values)
|
||||
|
|
|
@ -8,18 +8,21 @@ class IcingaApiUser extends IcingaObject
|
|||
{
|
||||
protected $table = 'icinga_apiuser';
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
// TODO: Enable (and add table) if required
|
||||
protected $supportsImports = false;
|
||||
|
||||
protected $defaultProperties = array(
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
'password' => null,
|
||||
'client_dn' => null,
|
||||
'permissions' => null,
|
||||
);
|
||||
];
|
||||
|
||||
protected function renderPassword()
|
||||
{
|
||||
|
|
|
@ -84,6 +84,10 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||
|
||||
public function set($key, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
return $this->remove($key);
|
||||
}
|
||||
|
||||
if ($value instanceof IcingaCommandArgument) {
|
||||
$argument = $value;
|
||||
} else {
|
||||
|
@ -337,6 +341,15 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||
return $arguments->loadFromDb();
|
||||
}
|
||||
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
foreach ($this->arguments as $argument) {
|
||||
$argument->setBeingLoadedFromDb();
|
||||
}
|
||||
$this->refreshIndex();
|
||||
$this->cloneStored();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||
|
@ -349,8 +362,14 @@ class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|||
if ($argument->shouldBeRemoved()) {
|
||||
$deleted[] = $key;
|
||||
} else {
|
||||
$argument->set('command_id', $this->object->get('id'));
|
||||
$argument->store($db);
|
||||
if ($argument->hasBeenModified()) {
|
||||
if ($argument->hasBeenLoadedFromDb()) {
|
||||
$argument->setLoadedProperty('command_id', $this->object->get('id'));
|
||||
} else {
|
||||
$argument->set('command_id', $this->object->get('id'));
|
||||
}
|
||||
$argument->store($db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,11 @@ class IcingaCommand extends IcingaObject implements ObjectWithArguments, ExportI
|
|||
|
||||
protected $type = 'CheckCommand';
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
|
|
@ -7,7 +7,9 @@ use RuntimeException;
|
|||
|
||||
class IcingaCommandArgument extends IcingaObject
|
||||
{
|
||||
protected $keyName = 'id';
|
||||
protected $keyName = ['command_id', 'argument_name'];
|
||||
|
||||
protected $autoincKeyName = 'id';
|
||||
|
||||
protected $table = 'icinga_command_argument';
|
||||
|
||||
|
@ -129,6 +131,7 @@ class IcingaCommandArgument extends IcingaObject
|
|||
}
|
||||
|
||||
$this->transformPlainArgumentValue($plain);
|
||||
unset($plain->command_id);
|
||||
|
||||
// Will happen only combined with $skipDefaults
|
||||
if (array_keys((array) $plain) === ['value']) {
|
||||
|
|
|
@ -16,6 +16,7 @@ class IcingaDependency extends IcingaObject implements ExportInterface
|
|||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
@ -34,6 +35,8 @@ class IcingaDependency extends IcingaObject implements ExportInterface
|
|||
'parent_service_by_name' => null,
|
||||
];
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $supportsCustomVars = false;
|
||||
|
||||
protected $supportsImports = true;
|
||||
|
|
|
@ -15,8 +15,11 @@ class IcingaEndpoint extends IcingaObject
|
|||
|
||||
protected $supportsImports = true;
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'zone_id' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
|
|
|
@ -22,6 +22,7 @@ class IcingaHost extends IcingaObject implements ExportInterface
|
|||
|
||||
protected $defaultProperties = array(
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
@ -101,6 +102,8 @@ class IcingaHost extends IcingaObject implements ExportInterface
|
|||
/** @var HostGroupMembershipResolver */
|
||||
protected $hostgroupMembershipResolver;
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
public static function enumProperties(
|
||||
DbConnection $connection = null,
|
||||
$prefix = '',
|
||||
|
|
|
@ -14,6 +14,7 @@ class IcingaNotification extends IcingaObject implements ExportInterface
|
|||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
@ -31,6 +32,8 @@ class IcingaNotification extends IcingaObject implements ExportInterface
|
|||
'assign_filter' => null,
|
||||
];
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $supportsCustomVars = true;
|
||||
|
||||
protected $supportsFields = true;
|
||||
|
|
|
@ -79,6 +79,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
// property => IcingaObjectClass
|
||||
];
|
||||
|
||||
/** @var IcingaObjectMultiRelations[] */
|
||||
protected $loadedMultiRelations = [];
|
||||
|
||||
/**
|
||||
|
@ -250,6 +251,10 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
return $prefix . $this->relatedSets[$property];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $property
|
||||
* @return ExtensibleSet
|
||||
*/
|
||||
protected function getRelatedSet($property)
|
||||
{
|
||||
if (! array_key_exists($property, $this->loadedRelatedSets)) {
|
||||
|
@ -262,6 +267,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
return $this->loadedRelatedSets[$property];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ExtensibleSet[]
|
||||
*/
|
||||
protected function relatedSets()
|
||||
{
|
||||
$sets = [];
|
||||
|
@ -828,7 +836,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
{
|
||||
$this->assertGroupsSupport();
|
||||
if ($this->groups === null) {
|
||||
if ($this->hasBeenLoadedFromDb()) {
|
||||
if ($this->hasBeenLoadedFromDb() && $this->get('id')) {
|
||||
$this->groups = IcingaObjectGroups::loadForStoredObject($this);
|
||||
} else {
|
||||
$this->groups = new IcingaObjectGroups($this);
|
||||
|
@ -1398,7 +1406,11 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
if (PrefetchCache::shouldBeUsed()) {
|
||||
$this->vars = PrefetchCache::instance()->vars($this);
|
||||
} else {
|
||||
$this->vars = CustomVariables::loadForStoredObject($this);
|
||||
if ($this->get('id')) {
|
||||
$this->vars = CustomVariables::loadForStoredObject($this);
|
||||
} else {
|
||||
$this->vars = new CustomVariables();
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->getShortTableName() === 'host') {
|
||||
|
@ -1477,6 +1489,35 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
&& $this->get('object_type') === 'apply';
|
||||
}
|
||||
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
if ($this instanceof ObjectWithArguments && $this->gotArguments()) {
|
||||
$this->arguments()->setBeingLoadedFromDb();
|
||||
}
|
||||
if ($this->supportsImports() && $this->gotImports()) {
|
||||
$this->imports()->setBeingLoadedFromDb();
|
||||
}
|
||||
if ($this->supportsCustomVars() && $this->vars !== null) {
|
||||
$this->vars()->setBeingLoadedFromDb();
|
||||
}
|
||||
if ($this->supportsGroups() && $this->groups !== null) {
|
||||
$this->groups()->setBeingLoadedFromDb();
|
||||
}
|
||||
if ($this->supportsRanges() && $this->ranges === null) {
|
||||
$this->ranges()->setBeingLoadedFromDb();
|
||||
}
|
||||
|
||||
foreach ($this->loadedRelatedSets as $set) {
|
||||
$set->setBeingLoadedFromDb();
|
||||
}
|
||||
|
||||
foreach ($this->loadedMultiRelations as $multiRelation) {
|
||||
$multiRelation->setBeingLoadedFromDb();
|
||||
}
|
||||
|
||||
parent::setBeingLoadedFromDb();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotFoundError
|
||||
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||
|
@ -2147,6 +2188,11 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
return '';
|
||||
}
|
||||
|
||||
public function renderUuid()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -2773,6 +2819,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
|
||||
foreach ($p as $k => $v) {
|
||||
// Do not ship ids for IcingaObjects:
|
||||
if ($k === $this->getUuidColumn()) {
|
||||
continue;
|
||||
}
|
||||
if ($resolveIds) {
|
||||
if ($k === 'id' && $keepId === false && $this->hasProperty('object_name')) {
|
||||
continue;
|
||||
|
@ -2991,6 +3040,9 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
public function getUrlParams()
|
||||
{
|
||||
$params = [];
|
||||
if ($column = $this->getUuidColumn()) {
|
||||
return [$column => $this->getUniqueId()->toString()];
|
||||
}
|
||||
|
||||
if ($this->isApplyRule() && ! $this instanceof IcingaScheduledDowntime) {
|
||||
$params['id'] = $this->get('id');
|
||||
|
@ -3044,6 +3096,12 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||
if ($k === 'id' && $this->hasProperty('object_name')) {
|
||||
continue;
|
||||
}
|
||||
if ($k === $this->getUuidColumn()) {
|
||||
continue;
|
||||
}
|
||||
if ($k === 'disabled' && $v === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('_id' === substr($k, -3)) {
|
||||
$relKey = substr($k, 0, -3);
|
||||
|
|
|
@ -12,8 +12,11 @@ abstract class IcingaObjectGroup extends IcingaObject implements ExportInterface
|
|||
|
||||
protected $supportedInLegacy = true;
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
|
|
@ -274,7 +274,7 @@ class IcingaObjectGroups implements Iterator, Countable, IcingaConfigRenderer
|
|||
|
||||
$class = $this->getGroupClass();
|
||||
$this->groups = $class::loadAll($connection, $query, 'object_name');
|
||||
$this->cloneStored();
|
||||
$this->setBeingLoadedFromDb();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -314,12 +314,12 @@ class IcingaObjectGroups implements Iterator, Countable, IcingaConfigRenderer
|
|||
)
|
||||
);
|
||||
}
|
||||
$this->cloneStored();
|
||||
$this->setBeingLoadedFromDb();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function cloneStored()
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
$this->storedGroups = array();
|
||||
foreach ($this->groups as $k => $v) {
|
||||
|
@ -341,7 +341,7 @@ class IcingaObjectGroups implements Iterator, Countable, IcingaConfigRenderer
|
|||
|
||||
if (PrefetchCache::shouldBeUsed()) {
|
||||
$groups->groups = PrefetchCache::instance()->groups($object);
|
||||
$groups->cloneStored();
|
||||
$groups->setBeingLoadedFromDb();
|
||||
} else {
|
||||
$groups->loadFromDb();
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||
$this->imports = array_combine($keys, $keys);
|
||||
}
|
||||
|
||||
$this->cloneStored();
|
||||
$this->setBeingLoadedFromDb();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -355,12 +355,12 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
|||
]);
|
||||
}
|
||||
|
||||
$this->cloneStored();
|
||||
$this->setBeingLoadedFromDb();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function cloneStored()
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
$this->storedNames = $this->listImportNames();
|
||||
$this->modified = false;
|
||||
|
|
|
@ -323,7 +323,7 @@ class IcingaObjectMultiRelations implements Iterator, Countable, IcingaConfigRen
|
|||
|
||||
$class = $this->getRelatedClassName();
|
||||
$this->relations = $class::loadAll($connection, $query, 'object_name');
|
||||
$this->cloneStored();
|
||||
$this->setBeingLoadedFromDb();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -331,13 +331,10 @@ class IcingaObjectMultiRelations implements Iterator, Countable, IcingaConfigRen
|
|||
public function store()
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$stored = array_keys($this->stored);
|
||||
$relations = array_keys($this->relations);
|
||||
|
||||
$objectId = $this->object->id;
|
||||
$type = $this->getType();
|
||||
|
||||
$type = $this->getType();
|
||||
$objectCol = $type . '_id';
|
||||
$relationCol = $this->getRelationIdColumn() . '_id';
|
||||
|
@ -369,12 +366,12 @@ class IcingaObjectMultiRelations implements Iterator, Countable, IcingaConfigRen
|
|||
)
|
||||
);
|
||||
}
|
||||
$this->cloneStored();
|
||||
$this->setBeingLoadedFromDb();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function cloneStored()
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
$this->stored = array();
|
||||
foreach ($this->relations as $k => $v) {
|
||||
|
|
|
@ -11,6 +11,7 @@ class IcingaScheduledDowntime extends IcingaObject
|
|||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'zone_id' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
|
@ -24,6 +25,8 @@ class IcingaScheduledDowntime extends IcingaObject
|
|||
'with_services' => null,
|
||||
];
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $supportsImports = true;
|
||||
|
||||
protected $supportsRanges = true;
|
||||
|
|
|
@ -211,13 +211,18 @@ class IcingaScheduledDowntimeRanges implements Iterator, Countable, IcingaConfig
|
|||
->order('o.range_key');
|
||||
|
||||
$this->ranges = IcingaScheduledDowntimeRange::loadAll($connection, $query, 'range_key');
|
||||
$this->storedRanges = array();
|
||||
$this->setBeingLoadedFromDb();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
$this->storedRanges = [];
|
||||
|
||||
foreach ($this->ranges as $key => $range) {
|
||||
$this->storedRanges[$key] = clone($range);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function store()
|
||||
|
|
|
@ -23,8 +23,11 @@ class IcingaService extends IcingaObject implements ExportInterface
|
|||
|
||||
protected $table = 'icinga_service';
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
|
|
@ -10,8 +10,11 @@ class IcingaTimePeriod extends IcingaObject implements ExportInterface
|
|||
{
|
||||
protected $table = 'icinga_timeperiod';
|
||||
|
||||
protected $defaultProperties = array(
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'zone_id' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
|
@ -19,7 +22,7 @@ class IcingaTimePeriod extends IcingaObject implements ExportInterface
|
|||
'prefer_includes' => null,
|
||||
'display_name' => null,
|
||||
'update_method' => null,
|
||||
);
|
||||
];
|
||||
|
||||
protected $booleans = [
|
||||
'prefer_includes' => 'prefer_includes',
|
||||
|
|
|
@ -216,13 +216,18 @@ class IcingaTimePeriodRanges implements Iterator, Countable, IcingaConfigRendere
|
|||
/** @var IcingaTimePeriodRange $class */
|
||||
$class = $this->getClass();
|
||||
$this->ranges = $class::loadAll($connection, $query, 'range_key');
|
||||
$this->storedRanges = array();
|
||||
$this->setBeingLoadedFromDb();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setBeingLoadedFromDb()
|
||||
{
|
||||
$this->storedRanges = [];
|
||||
|
||||
foreach ($this->ranges as $key => $range) {
|
||||
$this->storedRanges[$key] = clone($range);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function store()
|
||||
|
|
|
@ -12,6 +12,7 @@ class IcingaUser extends IcingaObject implements ExportInterface
|
|||
|
||||
protected $defaultProperties = array(
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
@ -23,6 +24,8 @@ class IcingaUser extends IcingaObject implements ExportInterface
|
|||
'zone_id' => null,
|
||||
);
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $supportsGroups = true;
|
||||
|
||||
protected $supportsCustomVars = true;
|
||||
|
|
|
@ -6,8 +6,11 @@ class IcingaUserGroup extends IcingaObjectGroup
|
|||
{
|
||||
protected $table = 'icinga_usergroup';
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
|
|
@ -10,8 +10,11 @@ class IcingaZone extends IcingaObject
|
|||
{
|
||||
protected $table = 'icinga_zone';
|
||||
|
||||
protected $uuidColumn = 'uuid';
|
||||
|
||||
protected $defaultProperties = [
|
||||
'id' => null,
|
||||
'uuid' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
|
|
|
@ -56,8 +56,7 @@ class ServiceActions extends ServiceActionsHook
|
|||
$title = mt('director', 'Modify');
|
||||
} elseif (Util::hasPermission('director/monitoring/services')) {
|
||||
$monitoring = new Monitoring();
|
||||
if (
|
||||
$monitoring->isAvailable()
|
||||
if ($monitoring->isAvailable()
|
||||
&& $monitoring->authCanEditService(Auth::getInstance(), $hostname, $serviceName)
|
||||
) {
|
||||
$title = mt('director', 'Modify');
|
||||
|
|
|
@ -56,7 +56,8 @@ class HostgroupRestriction extends ObjectRestriction
|
|||
return true;
|
||||
}
|
||||
|
||||
if (! $host->hasBeenLoadedFromDb() || $host->hasModifiedGroups()) {
|
||||
// Hint: branched hosts have no id
|
||||
if (! $host->hasBeenLoadedFromDb() || $host->hasModifiedGroups() || $host->get('id') === null) {
|
||||
foreach ($this->listRestrictedHostgroups() as $group) {
|
||||
if ($host->hasGroup($group)) {
|
||||
return true;
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Web\Controller;
|
|||
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Db\Branch\BranchStore;
|
||||
use Icinga\Module\Director\Web\Widget\NotInBranchedHint;
|
||||
|
||||
trait BranchHelper
|
||||
{
|
||||
|
@ -47,4 +48,18 @@ trait BranchHelper
|
|||
{
|
||||
return $this->getBranchUuid() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @return bool
|
||||
*/
|
||||
protected function showNotInBranch($subject)
|
||||
{
|
||||
if ($this->getBranch()->isBranch()) {
|
||||
$this->content()->add(new NotInBranchedHint($subject, $this->getBranch(), $this->Auth()));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@ use Icinga\Exception\IcingaException;
|
|||
use Icinga\Exception\InvalidPropertyException;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectStore;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Db\Branch\BranchedObject;
|
||||
use Icinga\Module\Director\Db\Branch\UuidLookup;
|
||||
use Icinga\Module\Director\Deployment\DeploymentInfo;
|
||||
use Icinga\Module\Director\DirectorObject\Automation\ExportInterface;
|
||||
use Icinga\Module\Director\Exception\NestingError;
|
||||
|
@ -25,11 +27,15 @@ use Icinga\Module\Director\Web\Controller\Extension\ObjectRestrictions;
|
|||
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
||||
use Icinga\Module\Director\Web\ObjectPreview;
|
||||
use Icinga\Module\Director\Web\Table\ActivityLogTable;
|
||||
use Icinga\Module\Director\Web\Table\BranchActivityTable;
|
||||
use Icinga\Module\Director\Web\Table\GroupMemberTable;
|
||||
use Icinga\Module\Director\Web\Table\IcingaObjectDatafieldTable;
|
||||
use Icinga\Module\Director\Web\Tabs\ObjectTabs;
|
||||
use Icinga\Module\Director\Web\Widget\ObjectModificationBranchHint;
|
||||
use Icinga\Module\Director\Web\Widget\BranchedObjectHint;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use ipl\Html\Html;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
abstract class ObjectController extends ActionController
|
||||
{
|
||||
|
@ -60,7 +66,7 @@ abstract class ObjectController extends ActionController
|
|||
if ($this->getRequest()->isApiRequest()) {
|
||||
$handler = new IcingaObjectHandler($this->getRequest(), $this->getResponse(), $this->db());
|
||||
try {
|
||||
$this->eventuallyLoadObject();
|
||||
$this->loadOptionalObject();
|
||||
} catch (NotFoundError $e) {
|
||||
// Silently ignore the error, the handler will complain
|
||||
$handler->sendJsonError($e, 404);
|
||||
|
@ -80,7 +86,7 @@ abstract class ObjectController extends ActionController
|
|||
// now.
|
||||
exit;
|
||||
} else {
|
||||
$this->eventuallyLoadObject();
|
||||
$this->loadOptionalObject();
|
||||
if ($this->getRequest()->getActionName() === 'add') {
|
||||
$this->addSingleTab(
|
||||
sprintf($this->translate('Add %s'), ucfirst($this->getType())),
|
||||
|
@ -260,6 +266,7 @@ abstract class ObjectController extends ActionController
|
|||
if ($host = $this->params->get('host')) {
|
||||
$table->filterHost($host);
|
||||
}
|
||||
$this->showOptionalBranchActivity($table);
|
||||
$table->renderTo($this);
|
||||
}
|
||||
|
||||
|
@ -452,48 +459,85 @@ abstract class ObjectController extends ActionController
|
|||
return $this->assertPermission("director/$type");
|
||||
}
|
||||
|
||||
protected function eventuallyLoadObject()
|
||||
protected function loadOptionalObject()
|
||||
{
|
||||
if (null !== $this->params->get('name') || $this->params->get('id')) {
|
||||
if ($this->params->get('uuid') || null !== $this->params->get('name') || $this->params->get('id')) {
|
||||
$this->loadObject();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?UuidInterface
|
||||
* @throws InvalidPropertyException
|
||||
* @throws NotFoundError
|
||||
*/
|
||||
protected function getUuidFromUrl()
|
||||
{
|
||||
$key = null;
|
||||
if ($uuid = $this->params->get('uuid')) {
|
||||
$key = Uuid::fromString($uuid);
|
||||
} elseif ($id = $this->params->get('id')) {
|
||||
$key = (int) $id;
|
||||
} elseif (null !== ($name = $this->params->get('name'))) {
|
||||
$key = $name;
|
||||
}
|
||||
if ($key === null) {
|
||||
$request = $this->getRequest();
|
||||
if ($request->isApiRequest() && $request->isGet()) {
|
||||
$this->getResponse()->setHttpResponseCode(422);
|
||||
|
||||
throw new InvalidPropertyException(
|
||||
'Cannot load object, missing parameters'
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->requireUuid($key);
|
||||
}
|
||||
|
||||
protected function loadObject()
|
||||
{
|
||||
if ($this->object) {
|
||||
throw new ProgrammingError('Loading an object twice is not very efficient');
|
||||
}
|
||||
|
||||
$isApi = $this->getRequest()->isApiRequest();
|
||||
$store = new DbObjectStore($this->db());
|
||||
if ($id = $this->params->get('id')) {
|
||||
$key = (int) $id;
|
||||
} elseif (null !== ($name = $this->params->get('name'))) {
|
||||
$key = $name;
|
||||
}
|
||||
if ($key === null) {
|
||||
if ($isApi && $this->getRequest()->isGet()) {
|
||||
$this->getResponse()->setHttpResponseCode(422);
|
||||
$this->object = $this->loadSpecificObject($this->getTableName(), $this->getUuidFromUrl(), true);
|
||||
}
|
||||
|
||||
throw new InvalidPropertyException(
|
||||
'Cannot load object, missing parameters'
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
protected function loadSpecificObject($tableName, $key, $showHint = false)
|
||||
{
|
||||
$branch = $this->getBranch();
|
||||
$store->setBranch($branch);
|
||||
list($object, $modification) = $store->loadWithBranchModification(strtolower($this->getType()), $key);
|
||||
$branchedObject = BranchedObject::load($this->db(), $tableName, $key, $branch);
|
||||
$object = $branchedObject->getBranchedDbObject($this->db());
|
||||
assert($object instanceof IcingaObject);
|
||||
$object->setBeingLoadedFromDb();
|
||||
if (! $this->allowsObject($object)) {
|
||||
throw new NotFoundError('No such object available');
|
||||
}
|
||||
if ($branch->isBranch() && ! $isApi) {
|
||||
$this->content()->add(new ObjectModificationBranchHint($branch, $this->Auth(), $object, $modification));
|
||||
if ($showHint && $branch->isBranch() && ! $this->getRequest()->isApiRequest()) {
|
||||
$this->content()->add(new BranchedObjectHint($branch, $this->Auth(), $branchedObject));
|
||||
}
|
||||
|
||||
$this->object = $object;
|
||||
return $object;
|
||||
}
|
||||
|
||||
protected function requireUuid($key)
|
||||
{
|
||||
if (! $key instanceof UuidInterface) {
|
||||
$key = UuidLookup::findUuidForKey($key, $this->getTableName(), $this->db(), $this->getBranch());
|
||||
if ($key === null) {
|
||||
throw new NotFoundError('No such object available');
|
||||
}
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
protected function getTableName()
|
||||
{
|
||||
return DbObjectTypeRegistry::tableNameByType($this->getType());
|
||||
}
|
||||
|
||||
protected function addDeploymentLink()
|
||||
|
@ -618,4 +662,30 @@ abstract class ObjectController extends ActionController
|
|||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
protected function showOptionalBranchActivity($activityTable)
|
||||
{
|
||||
$branch = $this->getBranch();
|
||||
if ($branch->isBranch() && (int) $this->params->get('page', '1') === 1) {
|
||||
$table = new BranchActivityTable($branch->getUuid(), $this->db(), $this->object->getUniqueId());
|
||||
if (count($table) > 0) {
|
||||
$this->content()->add(Hint::info(Html::sprintf($this->translate(
|
||||
'The following modifications are visible in this %s only...'
|
||||
), Branch::requireHook()->linkToBranch(
|
||||
$branch,
|
||||
$this->Auth(),
|
||||
$this->translate('configuration branch')
|
||||
))));
|
||||
$this->content()->add($table);
|
||||
if (count($activityTable) === 0) {
|
||||
return;
|
||||
}
|
||||
$this->content()->add(Html::tag('br'));
|
||||
$this->content()->add(Hint::ok($this->translate(
|
||||
'...and the modifications below are already in the main branch:'
|
||||
)));
|
||||
$this->content()->add(Html::tag('br'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,11 @@ namespace Icinga\Module\Director\Web\Form;
|
|||
use Exception;
|
||||
use gipfl\IcingaWeb2\Url;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectStore;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Data\Db\DbObjectWithSettings;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Db\Branch\BranchModificationStore;
|
||||
use Icinga\Module\Director\Db\Branch\IcingaObjectModification;
|
||||
use Icinga\Module\Director\Exception\NestingError;
|
||||
use Icinga\Module\Director\Hook\IcingaObjectFormHook;
|
||||
use Icinga\Module\Director\IcingaConfig\StateFilterSet;
|
||||
|
@ -677,23 +676,7 @@ abstract class DirectorObjectForm extends DirectorForm
|
|||
: $this->translate('A new %s has successfully been created'),
|
||||
$this->translate($this->getObjectShortClassName())
|
||||
);
|
||||
if ($this->branch && $this->branch->isBranch()) {
|
||||
if ($object->shouldBeRenamed()) {
|
||||
$this->getElement('object_name')->addError(
|
||||
$this->translate('Renaming objects in branches is not (yet) supported')
|
||||
);
|
||||
return;
|
||||
}
|
||||
$store = new BranchModificationStore($this->getDb(), $object->getShortTableName());
|
||||
|
||||
$store->store(
|
||||
IcingaObjectModification::getModification($object),
|
||||
$object->get('id'),
|
||||
$this->branch->getUuid()
|
||||
);
|
||||
} else {
|
||||
$object->store($this->db);
|
||||
}
|
||||
$this->getDbObjectStore()->store($object);
|
||||
} else {
|
||||
if ($this->isApiRequest()) {
|
||||
$this->setHttpResponseCode(304);
|
||||
|
@ -933,22 +916,21 @@ abstract class DirectorObjectForm extends DirectorForm
|
|||
);
|
||||
}
|
||||
|
||||
if ($this->branch && $this->branch->isBranch()) {
|
||||
$store = new BranchModificationStore($this->getDb(), $object->getShortTableName());
|
||||
$store->store(
|
||||
IcingaObjectModification::delete($object),
|
||||
$object->get('id'),
|
||||
$this->branch->getUuid()
|
||||
);
|
||||
|
||||
$this->setSuccessUrl($url);
|
||||
} elseif ($object->delete()) {
|
||||
if ($this->getDbObjectStore()->delete($object)) {
|
||||
$this->setSuccessUrl($url);
|
||||
}
|
||||
// TODO: show object name and so
|
||||
$this->redirectOnSuccess($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DbObjectStore
|
||||
*/
|
||||
protected function getDbObjectStore()
|
||||
{
|
||||
$store = new DbObjectStore($this->getDb(), $this->branch);
|
||||
return $store;
|
||||
}
|
||||
|
||||
protected function addDeleteButton($label = null)
|
||||
{
|
||||
$object = $this->object;
|
||||
|
@ -1076,18 +1058,20 @@ abstract class DirectorObjectForm extends DirectorForm
|
|||
|
||||
public function loadObject($id)
|
||||
{
|
||||
if ($this->branch && $this->branch->isBranch()) {
|
||||
throw new \RuntimeException('Calling loadObject from form in a branch');
|
||||
}
|
||||
/** @var DbObject $class */
|
||||
$class = $this->getObjectClassname();
|
||||
if (is_int($id)) {
|
||||
$this->object = $class::loadWithAutoIncId($id, $this->db);
|
||||
if ($this->object->getKeyName() === 'id') {
|
||||
$this->addHidden('id', $id);
|
||||
}
|
||||
} else {
|
||||
$this->object = $class::load($id, $this->db);
|
||||
}
|
||||
|
||||
// TODO: hmmmm...
|
||||
if (! is_array($id) && $this->object->getKeyName() === 'id') {
|
||||
$this->addHidden('id', $id);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
namespace Icinga\Module\Director\Web\Table;
|
||||
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Db\Branch\ObjectModification;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Db\Branch\BranchActivity;
|
||||
use Icinga\Module\Director\Util;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use gipfl\IcingaWeb2\Table\ZfQueryBasedTable;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class BranchActivityTable extends ZfQueryBasedTable
|
||||
|
@ -17,9 +16,13 @@ class BranchActivityTable extends ZfQueryBasedTable
|
|||
/** @var UuidInterface */
|
||||
protected $branchUuid;
|
||||
|
||||
public function __construct(UuidInterface $branchUuid, $db)
|
||||
/** @var ?UuidInterface */
|
||||
protected $objectUuid;
|
||||
|
||||
public function __construct(UuidInterface $branchUuid, $db, UuidInterface $objectUuid = null)
|
||||
{
|
||||
$this->branchUuid = $branchUuid;
|
||||
$this->objectUuid = $objectUuid;
|
||||
parent::__construct($db);
|
||||
}
|
||||
|
||||
|
@ -30,93 +33,68 @@ class BranchActivityTable extends ZfQueryBasedTable
|
|||
|
||||
public function renderRow($row)
|
||||
{
|
||||
return $this->renderBranchRow($row);
|
||||
}
|
||||
|
||||
public function renderBranchRow($row)
|
||||
{
|
||||
$ts = $row->change_time / 1000;
|
||||
$ts = (int) floor($row->timestamp_ns / 1000000);
|
||||
$this->splitByDay($ts);
|
||||
$changes = ObjectModification::fromSerialization(json_decode($row->change_set));
|
||||
$action = 'action-' . $changes->getAction(). ' branched'; // not gray
|
||||
$activity = BranchActivity::fromDbRow($row);
|
||||
return $this::tr([
|
||||
$this::td($this->makeBranchLink(
|
||||
$changes,
|
||||
Uuid::fromBytes($row->uuid),
|
||||
Uuid::fromBytes($row->branch_uuid)
|
||||
))->setSeparator(' '),
|
||||
$this::td($this->makeBranchLink($activity))->setSeparator(' '),
|
||||
$this::td(strftime('%H:%M:%S', $ts))
|
||||
])->addAttributes(['class' => $action]);
|
||||
])->addAttributes(['class' => ['action-' . $activity->getAction(), 'branched']]);
|
||||
}
|
||||
|
||||
protected function linkObject($type, $name)
|
||||
protected function linkObject(BranchActivity $activity)
|
||||
{
|
||||
// $type, UuidInterface $uuid
|
||||
// Later on replacing, service_set -> serviceset
|
||||
|
||||
// multi column key :(
|
||||
if ($type === 'service') {
|
||||
return "\"$name\"";
|
||||
}
|
||||
|
||||
$type = preg_replace('/^icinga_/', '', $activity->getObjectTable());
|
||||
return Link::create(
|
||||
"\"$name\"",
|
||||
$activity->getObjectName(),
|
||||
'director/' . str_replace('_', '', $type),
|
||||
['name' => $name],
|
||||
['uuid' => $activity->getObjectUuid()->toString()],
|
||||
['title' => $this->translate('Jump to this object')]
|
||||
);
|
||||
}
|
||||
|
||||
protected function makeBranchLink(ObjectModification $modification, UuidInterface $uuid, UuidInterface $branch)
|
||||
protected function makeBranchLink(BranchActivity $activity)
|
||||
{
|
||||
/** @var string|DbObject $class */
|
||||
$class = $modification->getClassName();
|
||||
$type = $class::create([])->getShortTableName();
|
||||
// TODO: short type in table, not class name
|
||||
$keyParams = $modification->getKeyParams();
|
||||
if (is_object($keyParams)) {
|
||||
$keyParams = (array)$keyParams;
|
||||
}
|
||||
if (is_array($keyParams)) {
|
||||
if (array_keys($keyParams) === ['object_name']) {
|
||||
$name = $keyParams['object_name'];
|
||||
} else {
|
||||
$name = json_encode($keyParams);
|
||||
}
|
||||
} else {
|
||||
$name = $keyParams;
|
||||
}
|
||||
$author = 'branch owner';
|
||||
$type = preg_replace('/^icinga_/', '', $activity->getObjectTable());
|
||||
|
||||
if (Util::hasPermission('director/showconfig')) {
|
||||
// Later on replacing, service_set -> serviceset
|
||||
$id = 0; // $row->id
|
||||
|
||||
return [
|
||||
'[' . $author . ']',
|
||||
'[' . $activity->getAuthor() . ']',
|
||||
Link::create(
|
||||
$modification->getAction(),
|
||||
$activity->getAction(),
|
||||
'director/branch/activity',
|
||||
array_merge(['uuid' => $uuid->toString()], $this->extraParams),
|
||||
array_merge(['ts' => $activity->getTimestampNs()], $this->extraParams),
|
||||
['title' => $this->translate('Show details related to this change')]
|
||||
),
|
||||
str_replace('_', ' ', $type),
|
||||
$this->linkObject($type, $name)
|
||||
$this->linkObject($activity)
|
||||
];
|
||||
} else {
|
||||
return sprintf(
|
||||
'[%s] %s %s "%s"',
|
||||
$author,
|
||||
$modification->getAction(),
|
||||
$activity->getAuthor(),
|
||||
$activity->getAction(),
|
||||
$type,
|
||||
$name
|
||||
'object name'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function prepareQuery()
|
||||
{
|
||||
return $this->db()->select()->from('director_branch_activity')
|
||||
->where('branch_uuid = ?', $this->branchUuid->getBytes())
|
||||
->order('change_time DESC');
|
||||
/** @var Db $connection */
|
||||
$connection = $this->connection();
|
||||
$query = $this->db()->select()->from(['ba' => 'director_branch_activity'], 'ba.*')
|
||||
->join(['b' => 'director_branch'], 'b.uuid = ba.branch_uuid', ['b.owner'])
|
||||
->where('branch_uuid = ?', $connection->quoteBinary($this->branchUuid->getBytes()))
|
||||
->order('timestamp_ns DESC');
|
||||
if ($this->objectUuid) {
|
||||
$query->where('ba.object_uuid = ?', $connection->quoteBinary($this->objectUuid->getBytes()));
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Web\Table;
|
||||
|
||||
use gipfl\IcingaWeb2\Data\SimpleQueryPaginationAdapter;
|
||||
use gipfl\IcingaWeb2\Table\QueryBasedTable;
|
||||
use Icinga\Data\DataArray\ArrayDatasource;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Objects\IcingaCommand;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
|
||||
class BranchedIcingaCommandArgumentTable extends QueryBasedTable
|
||||
{
|
||||
/** @var IcingaCommand */
|
||||
protected $command;
|
||||
|
||||
/** @var Branch */
|
||||
protected $branch;
|
||||
|
||||
protected $searchColumns = [
|
||||
'ca.argument_name',
|
||||
'ca.argument_value',
|
||||
];
|
||||
|
||||
public function __construct(IcingaCommand $command, Branch $branch)
|
||||
{
|
||||
$this->command = $command;
|
||||
$this->branch = $branch;
|
||||
$this->getAttributes()->set('data-base-target', '_self');
|
||||
}
|
||||
|
||||
public function renderRow($row)
|
||||
{
|
||||
return $this::row([
|
||||
Link::create($row->argument_name, 'director/command/arguments', [
|
||||
'argument' => $row->argument_name,
|
||||
'uuid' => $this->command->getUniqueId()->toString(),
|
||||
]),
|
||||
$row->argument_value
|
||||
]);
|
||||
}
|
||||
|
||||
public function getColumnsToBeRendered()
|
||||
{
|
||||
return [
|
||||
$this->translate('Argument'),
|
||||
$this->translate('Value'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getPaginationAdapter()
|
||||
{
|
||||
return new SimpleQueryPaginationAdapter($this->getQuery());
|
||||
}
|
||||
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->prepareQuery();
|
||||
}
|
||||
|
||||
protected function fetchQueryRows()
|
||||
{
|
||||
return $this->getQuery()->fetchAll();
|
||||
}
|
||||
|
||||
protected function prepareQuery()
|
||||
{
|
||||
$list = [];
|
||||
foreach ($this->command->arguments()->toPlainObject() as $name => $argument) {
|
||||
$new = (object) [];
|
||||
$new->argument_name = $name;
|
||||
$new->argument_value = isset($argument->value) ? $argument->value : null;
|
||||
$list[] = $new;
|
||||
}
|
||||
|
||||
return (new ArrayDatasource($list))->select();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
namespace Icinga\Module\Director\Web\Table;
|
||||
|
||||
use Icinga\Data\DataArray\ArrayDatasource;
|
||||
use Icinga\Module\Director\Data\Json;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Db\Branch\BranchModificationStore;
|
||||
use Icinga\Module\Director\Objects\IcingaCommand;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use gipfl\IcingaWeb2\Table\ZfQueryBasedTable;
|
||||
|
@ -11,20 +16,19 @@ class IcingaCommandArgumentTable extends ZfQueryBasedTable
|
|||
/** @var IcingaCommand */
|
||||
protected $command;
|
||||
|
||||
protected $searchColumns = array(
|
||||
/** @var Branch */
|
||||
protected $branch;
|
||||
|
||||
protected $searchColumns = [
|
||||
'ca.argument_name',
|
||||
'ca.argument_value',
|
||||
);
|
||||
];
|
||||
|
||||
public static function create(IcingaCommand $command)
|
||||
{
|
||||
$self = new static($command->getConnection());
|
||||
$self->command = $command;
|
||||
return $self;
|
||||
}
|
||||
|
||||
public function assemble()
|
||||
public function __construct(IcingaCommand $command, Branch $branch)
|
||||
{
|
||||
$this->command = $command;
|
||||
$this->branch = $branch;
|
||||
parent::__construct($command->getConnection());
|
||||
$this->getAttributes()->set('data-base-target', '_self');
|
||||
}
|
||||
|
||||
|
@ -32,8 +36,8 @@ class IcingaCommandArgumentTable extends ZfQueryBasedTable
|
|||
{
|
||||
return $this::row([
|
||||
Link::create($row->argument_name, 'director/command/arguments', [
|
||||
'argument_id' => $row->id,
|
||||
'name' => $this->command->getObjectName()
|
||||
'argument' => $row->argument_name,
|
||||
'name' => $this->command->getObjectName()
|
||||
]),
|
||||
$row->argument_value
|
||||
]);
|
||||
|
@ -49,6 +53,27 @@ class IcingaCommandArgumentTable extends ZfQueryBasedTable
|
|||
|
||||
public function prepareQuery()
|
||||
{
|
||||
$db = $this->db();
|
||||
if ($this->branch->isBranch()) {
|
||||
return (new ArrayDatasource((array) $this->command->arguments()->toPlainObject()))->select();
|
||||
/** @var Db $connection */
|
||||
$connection = $this->connection();
|
||||
$store = new BranchModificationStore($connection, 'command');
|
||||
$modification = $store->loadOptionalModificationByName(
|
||||
$this->command->getObjectName(),
|
||||
$this->branch->getUuid()
|
||||
);
|
||||
if ($modification) {
|
||||
$props = $modification->getProperties()->jsonSerialize();
|
||||
if (isset($props->arguments)) {
|
||||
return new ArrayDatasource((array) $this->command->arguments()->toPlainObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
$id = $this->command->get('id');
|
||||
if ($id === null) {
|
||||
return new ArrayDatasource([]);
|
||||
}
|
||||
return $this->db()->select()->from(
|
||||
['ca' => 'icinga_command_argument'],
|
||||
[
|
||||
|
@ -58,7 +83,7 @@ class IcingaCommandArgumentTable extends ZfQueryBasedTable
|
|||
]
|
||||
)->where(
|
||||
'ca.command_id = ?',
|
||||
$this->command->get('id')
|
||||
$id
|
||||
)->order('ca.sort_order')->order('ca.argument_name')->limit(100);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use ipl\Html\Html;
|
|||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use gipfl\IcingaWeb2\Table\ZfQueryBasedTable;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
class IcingaHostServiceTable extends ZfQueryBasedTable
|
||||
{
|
||||
|
@ -23,6 +24,9 @@ class IcingaHostServiceTable extends ZfQueryBasedTable
|
|||
/** @var string|null */
|
||||
protected $highlightedService;
|
||||
|
||||
/** @var ?UuidInterface */
|
||||
protected $branchUuid;
|
||||
|
||||
protected $searchColumns = [
|
||||
'service',
|
||||
];
|
||||
|
@ -45,6 +49,12 @@ class IcingaHostServiceTable extends ZfQueryBasedTable
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setBranchUuid(UuidInterface $uuid)
|
||||
{
|
||||
$this->branchUuid = $uuid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHost(IcingaHost $host)
|
||||
{
|
||||
$this->host = $host;
|
||||
|
|
|
@ -13,6 +13,7 @@ use Icinga\Module\Director\Restriction\ObjectRestriction;
|
|||
use gipfl\IcingaWeb2\Link;
|
||||
use gipfl\IcingaWeb2\Table\ZfQueryBasedTable;
|
||||
use gipfl\IcingaWeb2\Url;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Zend_Db_Select as ZfSelect;
|
||||
|
||||
|
@ -25,7 +26,7 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
'object_name' => 'o.object_name',
|
||||
'object_type' => 'o.object_type',
|
||||
'disabled' => 'o.disabled',
|
||||
'id' => 'o.id',
|
||||
'uuid' => 'o.uuid',
|
||||
];
|
||||
|
||||
protected $searchColumns = ['o.object_name'];
|
||||
|
@ -44,6 +45,10 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
/** @var IcingaObject */
|
||||
protected $dummyObject;
|
||||
|
||||
protected $leftSubQuery;
|
||||
|
||||
protected $rightSubQuery;
|
||||
|
||||
/** @var Auth */
|
||||
private $auth;
|
||||
|
||||
|
@ -147,7 +152,7 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
{
|
||||
$type = $this->baseObjectUrl;
|
||||
$url = Url::fromPath("director/${type}", [
|
||||
'name' => $row->object_name
|
||||
'uuid' => Uuid::fromBytes($row->uuid)->toString()
|
||||
]);
|
||||
|
||||
return static::td(Link::create($this->getMainLinkLabel($row), $url));
|
||||
|
@ -167,6 +172,9 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
|
||||
public function renderRow($row)
|
||||
{
|
||||
if (isset($row->uuid) && is_resource($row->uuid)) {
|
||||
$row->uuid = stream_get_contents($row->uuid);
|
||||
}
|
||||
$tr = static::tr([
|
||||
$this->renderObjectNameColumn($row),
|
||||
$this->renderExtraColumns($row)
|
||||
|
@ -226,6 +234,7 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
|
||||
protected function loadRestrictions()
|
||||
{
|
||||
/** @var Db $db */
|
||||
$db = $this->connection();
|
||||
$auth = $this->getAuth();
|
||||
|
||||
|
@ -249,7 +258,9 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
|
||||
protected function branchifyColumns($columns)
|
||||
{
|
||||
$result = [];
|
||||
$result = [
|
||||
'uuid' => 'COALESCE(o.uuid, bo.uuid)'
|
||||
];
|
||||
$ignore = ['o.id'];
|
||||
foreach ($columns as $alias => $column) {
|
||||
if (substr($column, 0, 2) === 'o.' && ! in_array($column, $ignore)) {
|
||||
|
@ -257,6 +268,11 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
$column = "COALESCE(b$column, $column)";
|
||||
}
|
||||
|
||||
// Used in Service Tables:
|
||||
if ($column === 'h.object_name' && $alias = 'host') {
|
||||
$column = "COALESCE(bo.host, $column)";
|
||||
}
|
||||
|
||||
$result[$alias] = $column;
|
||||
}
|
||||
|
||||
|
@ -299,19 +315,21 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||
['bo' => "branched_$table"],
|
||||
// TODO: PgHexFunc
|
||||
$this->db()->quoteInto(
|
||||
'bo.object_id = o.id AND bo.branch_uuid = ?',
|
||||
'bo.uuid = o.uuid AND bo.branch_uuid = ?',
|
||||
$conn->quoteBinary($this->branchUuid->getBytes())
|
||||
),
|
||||
[]
|
||||
)->where("(bo.deleted IS NULL OR bo.deleted = 'n')");
|
||||
)->where("(bo.branch_deleted IS NULL OR bo.branch_deleted = 'n')");
|
||||
$this->applyObjectTypeFilter($query, $right);
|
||||
$right->joinRight(
|
||||
['bo' => "branched_$table"],
|
||||
'bo.object_id = o.id',
|
||||
'bo.uuid = o.uuid',
|
||||
[]
|
||||
)
|
||||
->where('o.id IS NULL')
|
||||
->where('o.uuid IS NULL')
|
||||
->where('bo.branch_uuid = ?', $conn->quoteBinary($this->branchUuid->getBytes()));
|
||||
$this->leftSubQuery = $query;
|
||||
$this->rightSubQuery = $right;
|
||||
$query = $this->db()->select()->union([
|
||||
'l' => new DbSelectParenthesis($query),
|
||||
'r' => new DbSelectParenthesis($right),
|
||||
|
|
|
@ -13,6 +13,7 @@ class ObjectsTableCommand extends ObjectsTable implements FilterableByUsage
|
|||
];
|
||||
|
||||
protected $columns = [
|
||||
'uuid' => 'o.uuid',
|
||||
'object_name' => 'o.object_name',
|
||||
'object_type' => 'o.object_type',
|
||||
'disabled' => 'o.disabled',
|
||||
|
|
|
@ -21,7 +21,7 @@ class ObjectsTableHost extends ObjectsTable
|
|||
'display_name' => 'o.display_name',
|
||||
'address' => 'o.address',
|
||||
'disabled' => 'o.disabled',
|
||||
'id' => 'o.id',
|
||||
'uuid' => 'o.uuid',
|
||||
];
|
||||
|
||||
protected $showColumns = [
|
||||
|
@ -34,7 +34,7 @@ class ObjectsTableHost extends ObjectsTable
|
|||
$this->enableMultiSelect(
|
||||
'director/hosts/edit',
|
||||
'director/hosts',
|
||||
['name']
|
||||
['uuid']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use ipl\Html\Html;
|
|||
use gipfl\IcingaWeb2\Table\Extension\MultiSelect;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use gipfl\IcingaWeb2\Url;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class ObjectsTableService extends ObjectsTable
|
||||
{
|
||||
|
@ -13,30 +14,28 @@ class ObjectsTableService extends ObjectsTable
|
|||
|
||||
protected $type = 'service';
|
||||
|
||||
protected $columns = [
|
||||
'object_name' => 'o.object_name',
|
||||
'disabled' => 'o.disabled',
|
||||
'host' => 'h.object_name',
|
||||
'host_object_type' => 'h.object_type',
|
||||
'host_disabled' => 'h.disabled',
|
||||
'id' => 'o.id',
|
||||
'uuid' => 'o.uuid',
|
||||
'blacklisted' => "CASE WHEN hsb.service_id IS NULL THEN 'n' ELSE 'y' END",
|
||||
];
|
||||
|
||||
protected $searchColumns = [
|
||||
'o.object_name',
|
||||
'h.object_name'
|
||||
];
|
||||
|
||||
public function getColumns()
|
||||
{
|
||||
return [
|
||||
'object_name' => 'o.object_name',
|
||||
'disabled' => 'o.disabled',
|
||||
'host' => 'h.object_name',
|
||||
'host_object_type' => 'h.object_type',
|
||||
'host_disabled' => 'h.disabled',
|
||||
'id' => 'o.id',
|
||||
'blacklisted' => "CASE WHEN hsb.service_id IS NULL THEN 'n' ELSE 'y' END",
|
||||
];
|
||||
}
|
||||
|
||||
public function assemble()
|
||||
{
|
||||
$this->enableMultiSelect(
|
||||
'director/services/edit',
|
||||
'director/services',
|
||||
['id']
|
||||
['uuid']
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -50,11 +49,27 @@ class ObjectsTableService extends ObjectsTable
|
|||
|
||||
public function renderRow($row)
|
||||
{
|
||||
$url = Url::fromPath('director/service/edit', [
|
||||
'name' => $row->object_name,
|
||||
'host' => $row->host,
|
||||
'id' => $row->id,
|
||||
]);
|
||||
$params = [
|
||||
'uuid' => Uuid::fromBytes($row->uuid)->toString(),
|
||||
];
|
||||
if ($row->host !== null) {
|
||||
$params['host'] = $row->host;
|
||||
}
|
||||
$url = Url::fromPath('director/service/edit', $params);
|
||||
/*
|
||||
if ($this->branchUuid) {
|
||||
$url = Url::fromPath('director/service/edit', [
|
||||
'uuid' => Uuid::fromBytes($row->uuid)->toString(),
|
||||
'host' => $row->host,
|
||||
]);
|
||||
} else {
|
||||
$url = Url::fromPath('director/service/edit', [
|
||||
'name' => $row->object_name,
|
||||
'host' => $row->host,
|
||||
'id' => $row->id,
|
||||
]);
|
||||
}
|
||||
*/
|
||||
|
||||
$caption = $row->host === null
|
||||
? Html::tag('span', ['class' => 'error'], '- none -')
|
||||
|
@ -70,27 +85,40 @@ class ObjectsTableService extends ObjectsTable
|
|||
]);
|
||||
|
||||
$attributes = $tr->getAttributes();
|
||||
$classes = $this->getRowClasses($row);
|
||||
if ($row->host_disabled === 'y' || $row->disabled === 'y') {
|
||||
$attributes->add('class', 'disabled');
|
||||
$classes[] = 'disabled';
|
||||
}
|
||||
if ($row->blacklisted === 'y') {
|
||||
$attributes->add('class', 'strike-links');
|
||||
$classes[] = 'strike-links';
|
||||
}
|
||||
$attributes->add('class', $classes);
|
||||
|
||||
return $tr;
|
||||
}
|
||||
|
||||
public function prepareQuery()
|
||||
{
|
||||
return parent::prepareQuery()->joinLeft(
|
||||
['h' => 'icinga_host'],
|
||||
'o.host_id = h.id',
|
||||
[]
|
||||
)->joinLeft(
|
||||
['hsb' => 'icinga_host_service_blacklist'],
|
||||
'hsb.service_id = o.id AND hsb.host_id = o.host_id',
|
||||
[]
|
||||
)->where('o.service_set_id IS NULL')
|
||||
->order('o.object_name')->order('h.object_name');
|
||||
$query = parent::prepareQuery();
|
||||
if ($this->branchUuid) {
|
||||
$queries = [$this->leftSubQuery, $this->rightSubQuery];
|
||||
} else {
|
||||
$queries = [$query];
|
||||
}
|
||||
|
||||
foreach ($queries as $subQuery) {
|
||||
$subQuery->joinLeft(
|
||||
['h' => 'icinga_host'],
|
||||
'o.host_id = h.id',
|
||||
[]
|
||||
)->joinLeft(
|
||||
['hsb' => 'icinga_host_service_blacklist'],
|
||||
'hsb.service_id = o.id AND hsb.host_id = o.host_id',
|
||||
[]
|
||||
)->where('o.service_set_id IS NULL')
|
||||
->order('o.object_name')->order('h.object_name');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,12 +127,12 @@ class ActivityLogInfo extends HtmlDocument
|
|||
$this->add($this->getInfoTable());
|
||||
if ($tabName === 'old') {
|
||||
// $title = sprintf('%s former config', $this->entry->object_name);
|
||||
$diffs = $this->getConfigDiffs($this->oldConfig(), $this->emptyConfig());
|
||||
$diffs = IcingaConfigDiff::getDiffs($this->oldConfig(), $this->emptyConfig());
|
||||
} elseif ($tabName === 'new') {
|
||||
// $title = sprintf('%s new config', $this->entry->object_name);
|
||||
$diffs = $this->getConfigDiffs($this->emptyConfig(), $this->newConfig());
|
||||
$diffs = IcingaConfigDiff::getDiffs($this->emptyConfig(), $this->newConfig());
|
||||
} else {
|
||||
$diffs = $this->getConfigDiffs($this->oldConfig(), $this->newConfig());
|
||||
$diffs = IcingaConfigDiff::getDiffs($this->oldConfig(), $this->newConfig());
|
||||
}
|
||||
|
||||
$this->addDiffs($diffs);
|
||||
|
@ -399,41 +399,6 @@ class ActivityLogInfo extends HtmlDocument
|
|||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IcingaConfig $oldConfig
|
||||
* @param IcingaConfig $newConfig
|
||||
* @return ValidHtml[]
|
||||
*/
|
||||
protected function getConfigDiffs(IcingaConfig $oldConfig, IcingaConfig $newConfig)
|
||||
{
|
||||
$oldFileNames = $oldConfig->getFileNames();
|
||||
$newFileNames = $newConfig->getFileNames();
|
||||
|
||||
$fileNames = array_merge($oldFileNames, $newFileNames);
|
||||
|
||||
$diffs = [];
|
||||
foreach ($fileNames as $filename) {
|
||||
if (in_array($filename, $oldFileNames)) {
|
||||
$left = $oldConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$left = '';
|
||||
}
|
||||
|
||||
if (in_array($filename, $newFileNames)) {
|
||||
$right = $newConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$right = '';
|
||||
}
|
||||
if ($left === $right) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$diffs[$filename] = new SideBySideDiff(new PhpDiff($left, $right));
|
||||
}
|
||||
|
||||
return $diffs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IcingaObject
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
|
|
|
@ -5,17 +5,16 @@ namespace Icinga\Module\Director\Web\Widget;
|
|||
use gipfl\Translation\TranslationHelper;
|
||||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use Icinga\Module\Director\Db\Branch\ObjectModification;
|
||||
use Icinga\Module\Director\Db\Branch\BranchedObject;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlDocument;
|
||||
|
||||
class ObjectModificationBranchHint extends HtmlDocument
|
||||
class BranchedObjectHint extends HtmlDocument
|
||||
{
|
||||
use TranslationHelper;
|
||||
|
||||
public function __construct(Branch $branch, Auth $auth, DbObject $object, ObjectModification $modification = null)
|
||||
public function __construct(Branch $branch, Auth $auth, BranchedObject $object)
|
||||
{
|
||||
if (! $branch->isBranch()) {
|
||||
return;
|
||||
|
@ -30,7 +29,7 @@ class ObjectModificationBranchHint extends HtmlDocument
|
|||
}
|
||||
$link = $hook->linkToBranch($branch, $auth, $label);
|
||||
|
||||
if ($modification === null) {
|
||||
if (! $object->hasBeenTouchedByBranch()) {
|
||||
$this->add(Hint::info(Html::sprintf($this->translate(
|
||||
'Your changes will be stored in %s. The\'ll not be part of any deployment'
|
||||
. ' unless being merged'
|
||||
|
@ -38,23 +37,23 @@ class ObjectModificationBranchHint extends HtmlDocument
|
|||
return;
|
||||
}
|
||||
|
||||
if ($modification->isDeletion()) {
|
||||
if ($object->hasBeenDeletedByBranch()) {
|
||||
$this->add(Hint::info(Html::sprintf(
|
||||
$this->translate('This object has been deleted in %s'),
|
||||
$link
|
||||
)));
|
||||
} elseif ($modification->isModification()) {
|
||||
} elseif ($object->hasBeenCreatedByBranch()) {
|
||||
$this->add(Hint::info(Html::sprintf(
|
||||
$this->translate('This object has been created in %s'),
|
||||
$link
|
||||
)));
|
||||
} else {
|
||||
$this->add(Hint::info(Html::sprintf(
|
||||
$this->translate('This object has modifications visible only in %s'),
|
||||
// TODO: Also link to object modifications
|
||||
// $hook->linkToBranchedObject($this->translate('modifications'), $branch, $object, $auth),
|
||||
$link
|
||||
)));
|
||||
} else {
|
||||
$this->add(Hint::info(Html::sprintf(
|
||||
$this->translate('This object has been created in %s'),
|
||||
$link
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Web\Widget;
|
||||
|
||||
use gipfl\Diff\HtmlRenderer\SideBySideDiff;
|
||||
use gipfl\Diff\PhpDiff;
|
||||
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlDocument;
|
||||
use ipl\Html\ValidHtml;
|
||||
|
||||
class IcingaConfigDiff extends HtmlDocument
|
||||
{
|
||||
public function __construct(IcingaConfig $left, IcingaConfig $right)
|
||||
{
|
||||
foreach (static::getDiffs($left, $right) as $filename => $diff) {
|
||||
$this->add([
|
||||
Html::tag('h3', $filename),
|
||||
$diff
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IcingaConfig $oldConfig
|
||||
* @param IcingaConfig $newConfig
|
||||
* @return ValidHtml[]
|
||||
*/
|
||||
public static function getDiffs(IcingaConfig $oldConfig, IcingaConfig $newConfig)
|
||||
{
|
||||
$oldFileNames = $oldConfig->getFileNames();
|
||||
$newFileNames = $newConfig->getFileNames();
|
||||
|
||||
$fileNames = array_merge($oldFileNames, $newFileNames);
|
||||
|
||||
$diffs = [];
|
||||
foreach ($fileNames as $filename) {
|
||||
if (in_array($filename, $oldFileNames)) {
|
||||
$left = $oldConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$left = '';
|
||||
}
|
||||
|
||||
if (in_array($filename, $newFileNames)) {
|
||||
$right = $newConfig->getFile($filename)->getContent();
|
||||
} else {
|
||||
$right = '';
|
||||
}
|
||||
if ($left === $right) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$diffs[$filename] = new SideBySideDiff(new PhpDiff($left, $right));
|
||||
}
|
||||
|
||||
return $diffs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Web\Widget;
|
||||
|
||||
use gipfl\Translation\TranslationHelper;
|
||||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Director\Db\Branch\Branch;
|
||||
use ipl\Html\Html;
|
||||
|
||||
class NotInBranchedHint extends Hint
|
||||
{
|
||||
use TranslationHelper;
|
||||
|
||||
public function __construct($forbiddenAction, Branch $branch, Auth $auth)
|
||||
{
|
||||
parent::__construct(Html::sprintf(
|
||||
$this->translate('%s is not available while being in a Configuration Branch: %s'),
|
||||
$forbiddenAction,
|
||||
Branch::requireHook()->linkToBranch($branch, $auth, $branch->getName())
|
||||
), 'info');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
ALTER TABLE icinga_zone ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_zone SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_zone MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_timeperiod ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_timeperiod SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_timeperiod MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_command ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_command SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_command MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_apiuser ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_apiuser SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_apiuser MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_endpoint ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_endpoint SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_endpoint MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_host ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_host SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_host MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_service ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_service SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_service MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_hostgroup ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_hostgroup SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_hostgroup MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_servicegroup ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_servicegroup SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_servicegroup MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_user ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_user SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_user MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_usergroup ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_usergroup SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_usergroup MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_notification ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_notification SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_notification MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_dependency ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_dependency SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_dependency MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
ALTER TABLE icinga_scheduled_downtime ADD COLUMN uuid VARBINARY(16) DEFAULT NULL AFTER id;
|
||||
SET @tmp_uuid = LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'), '-',
|
||||
'4',
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
HEX(FLOOR(RAND() * 4 + 8)),
|
||||
LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'), '-',
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0'),
|
||||
LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0')
|
||||
));
|
||||
UPDATE icinga_scheduled_downtime SET uuid = UNHEX(LPAD(LPAD(HEX(id), 8, '0'), 32, REPLACE(@tmp_uuid, '-', ''))) WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_scheduled_downtime MODIFY COLUMN uuid VARBINARY(16) NOT NULL, ADD UNIQUE INDEX uuid (uuid);
|
||||
|
||||
|
||||
INSERT INTO director_schema_migration
|
||||
(schema_version, migration_time)
|
||||
VALUES (174, NOW());
|
|
@ -0,0 +1,484 @@
|
|||
CREATE TABLE director_branch (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
owner VARCHAR(255) NOT NULL,
|
||||
branch_name VARCHAR(255) NOT NULL,
|
||||
description TEXT DEFAULT NULL,
|
||||
ts_merge_request BIGINT DEFAULT NULL,
|
||||
PRIMARY KEY(uuid),
|
||||
UNIQUE KEY (branch_name)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE director_branch_activity (
|
||||
timestamp_ns BIGINT(20) NOT NULL,
|
||||
object_uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
action ENUM ('create', 'modify', 'delete') NOT NULL,
|
||||
object_table VARCHAR(64) NOT NULL,
|
||||
author VARCHAR(255) NOT NULL,
|
||||
former_properties LONGTEXT NOT NULL, -- json-encoded
|
||||
modified_properties LONGTEXT NOT NULL,
|
||||
PRIMARY KEY (timestamp_ns),
|
||||
INDEX object_uuid (object_uuid),
|
||||
INDEX branch_uuid (branch_uuid),
|
||||
CONSTRAINT branch_activity_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_host (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
address VARCHAR(255) DEFAULT NULL,
|
||||
address6 VARCHAR(45) DEFAULT NULL,
|
||||
check_command VARCHAR(255) DEFAULT NULL,
|
||||
max_check_attempts MEDIUMINT UNSIGNED DEFAULT NULL,
|
||||
check_period VARCHAR(255) DEFAULT NULL,
|
||||
check_interval VARCHAR(8) DEFAULT NULL,
|
||||
retry_interval VARCHAR(8) DEFAULT NULL,
|
||||
check_timeout SMALLINT UNSIGNED DEFAULT NULL,
|
||||
enable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_active_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_passive_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_event_handler ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_flapping ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_perfdata ENUM('y', 'n') DEFAULT NULL,
|
||||
event_command VARCHAR(255) DEFAULT NULL,
|
||||
flapping_threshold_high SMALLINT UNSIGNED DEFAULT NULL,
|
||||
flapping_threshold_low SMALLINT UNSIGNED DEFAULT NULL,
|
||||
volatile ENUM('y', 'n') DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
command_endpoint VARCHAR(255) DEFAULT NULL,
|
||||
notes TEXT DEFAULT NULL,
|
||||
notes_url VARCHAR(255) DEFAULT NULL,
|
||||
action_url VARCHAR(255) DEFAULT NULL,
|
||||
icon_image VARCHAR(255) DEFAULT NULL,
|
||||
icon_image_alt VARCHAR(255) DEFAULT NULL,
|
||||
has_agent ENUM('y', 'n') DEFAULT NULL,
|
||||
master_should_connect ENUM('y', 'n') DEFAULT NULL,
|
||||
accept_config ENUM('y', 'n') DEFAULT NULL,
|
||||
api_key VARCHAR(40) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_host_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_hostgroup (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_hostgroup_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_servicegroup (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_servicegroup_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_usergroup (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_usergroup_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_user (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
email VARCHAR(255) DEFAULT NULL,
|
||||
pager VARCHAR(255) DEFAULT NULL,
|
||||
enable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
period VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
states TEXT DEFAULT NULL,
|
||||
types TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_user_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_zone (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
parent VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
is_global ENUM('y', 'n') DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_zone_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_timeperiod (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
update_method VARCHAR(64) DEFAULT NULL COMMENT 'Usually LegacyTimePeriod',
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
prefer_includes ENUM('y', 'n') DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_timeperiod_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_command (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
methods_execute VARCHAR(64) DEFAULT NULL,
|
||||
command TEXT DEFAULT NULL,
|
||||
is_string ENUM('y', 'n') NULL,
|
||||
timeout SMALLINT UNSIGNED DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
arguments TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_command_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_apiuser (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
password VARCHAR(255) DEFAULT NULL,
|
||||
client_dn VARCHAR(64) DEFAULT NULL,
|
||||
permissions TEXT DEFAULT NULL COMMENT 'JSON-encoded permissions',
|
||||
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_apiuser_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_endpoint (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
host VARCHAR(255) DEFAULT NULL,
|
||||
port SMALLINT UNSIGNED DEFAULT NULL,
|
||||
log_duration VARCHAR(32) DEFAULT NULL,
|
||||
apiuser VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_endpoint_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_service (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
host VARCHAR(255) DEFAULT NULL,
|
||||
service_set VARCHAR(255) DEFAULT NULL,
|
||||
check_command VARCHAR(255) DEFAULT NULL,
|
||||
max_check_attempts MEDIUMINT UNSIGNED DEFAULT NULL,
|
||||
check_period VARCHAR(255) DEFAULT NULL,
|
||||
check_interval VARCHAR(8) DEFAULT NULL,
|
||||
retry_interval VARCHAR(8) DEFAULT NULL,
|
||||
check_timeout SMALLINT UNSIGNED DEFAULT NULL,
|
||||
enable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_active_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_passive_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_event_handler ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_flapping ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_perfdata ENUM('y', 'n') DEFAULT NULL,
|
||||
event_command VARCHAR(255) DEFAULT NULL,
|
||||
flapping_threshold_high SMALLINT UNSIGNED DEFAULT NULL,
|
||||
flapping_threshold_low SMALLINT UNSIGNED DEFAULT NULL,
|
||||
volatile ENUM('y', 'n') DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
command_endpoint VARCHAR(255) DEFAULT NULL,
|
||||
notes TEXT DEFAULT NULL,
|
||||
notes_url VARCHAR(255) DEFAULT NULL,
|
||||
action_url VARCHAR(255) DEFAULT NULL,
|
||||
icon_image VARCHAR(255) DEFAULT NULL,
|
||||
icon_image_alt VARCHAR(255) DEFAULT NULL,
|
||||
use_agent ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_for VARCHAR(255) DEFAULT NULL,
|
||||
use_var_overrides ENUM('y', 'n') DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
-- template_choice VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_service_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_notification (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||
host VARCHAR(255) DEFAULT NULL,
|
||||
service VARCHAR(255) DEFAULT NULL,
|
||||
times_begin INT(10) UNSIGNED DEFAULT NULL,
|
||||
times_end INT(10) UNSIGNED DEFAULT NULL,
|
||||
notification_interval INT(10) UNSIGNED DEFAULT NULL,
|
||||
command VARCHAR(255) DEFAULT NULL,
|
||||
period VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
|
||||
states TEXT DEFAULT NULL,
|
||||
types TEXT DEFAULT NULL,
|
||||
users TEXT DEFAULT NULL,
|
||||
usergroups TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_notification_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_scheduled_downtime (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
author VARCHAR(255) DEFAULT NULL,
|
||||
comment TEXT DEFAULT NULL,
|
||||
fixed ENUM('y', 'n') DEFAULT NULL,
|
||||
duration INT(10) UNSIGNED DEFAULT NULL,
|
||||
with_services ENUM('y', 'n') NULL DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_scheduled_downtime_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_dependency (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||
parent_host VARCHAR(255) DEFAULT NULL,
|
||||
parent_host_var VARCHAR(128) DEFAULT NULL,
|
||||
parent_service VARCHAR(255) DEFAULT NULL,
|
||||
child_host VARCHAR(255) DEFAULT NULL,
|
||||
child_service VARCHAR(255) DEFAULT NULL,
|
||||
disable_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
disable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
ignore_soft_states ENUM('y', 'n') DEFAULT NULL,
|
||||
period VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
parent_service_by_name VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_dependency_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO director_schema_migration
|
||||
(schema_version, migration_time)
|
||||
VALUES (175, NOW());
|
513
schema/mysql.sql
513
schema/mysql.sql
|
@ -231,12 +231,14 @@ CREATE TABLE director_setting (
|
|||
|
||||
CREATE TABLE icinga_zone (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
parent_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
is_global ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
CONSTRAINT icinga_zone_parent
|
||||
FOREIGN KEY parent_zone (parent_id)
|
||||
|
@ -265,6 +267,7 @@ CREATE TABLE icinga_zone_inheritance (
|
|||
|
||||
CREATE TABLE icinga_timeperiod (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
update_method VARCHAR(64) DEFAULT NULL COMMENT 'Usually LegacyTimePeriod',
|
||||
|
@ -273,6 +276,7 @@ CREATE TABLE icinga_timeperiod (
|
|||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
prefer_includes ENUM('y', 'n') DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name, zone_id),
|
||||
CONSTRAINT icinga_timeperiod_zone
|
||||
FOREIGN KEY zone (zone_id)
|
||||
|
@ -349,6 +353,7 @@ CREATE TABLE director_job_setting (
|
|||
|
||||
CREATE TABLE icinga_command (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') NOT NULL
|
||||
COMMENT 'external_object is an attempt to work with existing commands',
|
||||
|
@ -361,6 +366,7 @@ CREATE TABLE icinga_command (
|
|||
timeout SMALLINT UNSIGNED DEFAULT NULL,
|
||||
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
CONSTRAINT icinga_command_zone
|
||||
FOREIGN KEY zone (zone_id)
|
||||
|
@ -447,17 +453,20 @@ CREATE TABLE icinga_command_var (
|
|||
|
||||
CREATE TABLE icinga_apiuser (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
password VARCHAR(255) DEFAULT NULL,
|
||||
client_dn VARCHAR(64) DEFAULT NULL,
|
||||
permissions TEXT DEFAULT NULL COMMENT 'JSON-encoded permissions',
|
||||
PRIMARY KEY (id)
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE icinga_endpoint (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') NOT NULL,
|
||||
|
@ -467,6 +476,7 @@ CREATE TABLE icinga_endpoint (
|
|||
log_duration VARCHAR(32) DEFAULT NULL COMMENT '1d if not set',
|
||||
apiuser_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
CONSTRAINT icinga_endpoint_zone
|
||||
FOREIGN KEY zone (zone_id)
|
||||
|
@ -512,6 +522,7 @@ CREATE TABLE icinga_host_template_choice (
|
|||
|
||||
CREATE TABLE icinga_host (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
@ -547,6 +558,7 @@ CREATE TABLE icinga_host (
|
|||
api_key VARCHAR(40) DEFAULT NULL,
|
||||
template_choice_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
UNIQUE INDEX api_key (api_key),
|
||||
KEY search_idx (display_name),
|
||||
|
@ -671,6 +683,7 @@ CREATE TABLE icinga_service_template_choice (
|
|||
|
||||
CREATE TABLE icinga_service (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
@ -706,6 +719,7 @@ CREATE TABLE icinga_service (
|
|||
assign_filter TEXT DEFAULT NULL,
|
||||
template_choice_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE KEY object_key (object_name, host_id),
|
||||
CONSTRAINT icinga_service_host
|
||||
FOREIGN KEY host (host_id)
|
||||
|
@ -876,12 +890,14 @@ CREATE TABLE icinga_service_set_var (
|
|||
|
||||
CREATE TABLE icinga_hostgroup (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
KEY search_idx (display_name)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
@ -907,12 +923,14 @@ CREATE TABLE icinga_hostgroup_inheritance (
|
|||
|
||||
CREATE TABLE icinga_servicegroup (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
KEY search_idx (display_name)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
@ -1017,6 +1035,7 @@ CREATE TABLE icinga_hostgroup_parent (
|
|||
|
||||
CREATE TABLE icinga_user (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
@ -1027,6 +1046,7 @@ CREATE TABLE icinga_user (
|
|||
period_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name, zone_id),
|
||||
CONSTRAINT icinga_user_zone
|
||||
FOREIGN KEY zone (zone_id)
|
||||
|
@ -1137,12 +1157,14 @@ CREATE TABLE icinga_user_field (
|
|||
|
||||
CREATE TABLE icinga_usergroup (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
object_type ENUM('object', 'template') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
KEY search_idx (display_name),
|
||||
CONSTRAINT icinga_usergroup_zone
|
||||
|
@ -1204,6 +1226,7 @@ CREATE TABLE icinga_usergroup_parent (
|
|||
|
||||
CREATE TABLE icinga_notification (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
@ -1218,6 +1241,7 @@ CREATE TABLE icinga_notification (
|
|||
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
CONSTRAINT icinga_notification_host
|
||||
FOREIGN KEY host (host_id)
|
||||
REFERENCES icinga_host (id)
|
||||
|
@ -1707,6 +1731,7 @@ CREATE TABLE icinga_user_resolved_var (
|
|||
|
||||
CREATE TABLE icinga_dependency (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') NOT NULL,
|
||||
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
@ -1724,6 +1749,7 @@ CREATE TABLE icinga_dependency (
|
|||
assign_filter TEXT DEFAULT NULL,
|
||||
parent_service_by_name VARCHAR(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
CONSTRAINT icinga_dependency_parent_host
|
||||
FOREIGN KEY parent_host (parent_host_id)
|
||||
REFERENCES icinga_host (id)
|
||||
|
@ -1828,6 +1854,7 @@ CREATE TABLE icinga_timeperiod_exclude (
|
|||
|
||||
CREATE TABLE icinga_scheduled_downtime (
|
||||
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
object_name VARCHAR(255) NOT NULL,
|
||||
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') NOT NULL,
|
||||
|
@ -1840,6 +1867,7 @@ CREATE TABLE icinga_scheduled_downtime (
|
|||
duration INT(10) UNSIGNED DEFAULT NULL,
|
||||
with_services ENUM('y', 'n') NULL DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX uuid (uuid),
|
||||
UNIQUE INDEX object_name (object_name),
|
||||
CONSTRAINT icinga_scheduled_downtime_zone
|
||||
FOREIGN KEY zone (zone_id)
|
||||
|
@ -1882,6 +1910,487 @@ CREATE TABLE icinga_scheduled_downtime_range (
|
|||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE director_branch (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
owner VARCHAR(255) NOT NULL,
|
||||
branch_name VARCHAR(255) NOT NULL,
|
||||
description TEXT DEFAULT NULL,
|
||||
ts_merge_request BIGINT DEFAULT NULL,
|
||||
PRIMARY KEY(uuid),
|
||||
UNIQUE KEY (branch_name)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE director_branch_activity (
|
||||
timestamp_ns BIGINT(20) NOT NULL,
|
||||
object_uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
action ENUM ('create', 'modify', 'delete') NOT NULL,
|
||||
object_table VARCHAR(64) NOT NULL,
|
||||
author VARCHAR(255) NOT NULL,
|
||||
former_properties LONGTEXT NOT NULL, -- json-encoded
|
||||
modified_properties LONGTEXT NOT NULL,
|
||||
PRIMARY KEY (timestamp_ns),
|
||||
INDEX object_uuid (object_uuid),
|
||||
INDEX branch_uuid (branch_uuid),
|
||||
CONSTRAINT branch_activity_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_host (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
address VARCHAR(255) DEFAULT NULL,
|
||||
address6 VARCHAR(45) DEFAULT NULL,
|
||||
check_command VARCHAR(255) DEFAULT NULL,
|
||||
max_check_attempts MEDIUMINT UNSIGNED DEFAULT NULL,
|
||||
check_period VARCHAR(255) DEFAULT NULL,
|
||||
check_interval VARCHAR(8) DEFAULT NULL,
|
||||
retry_interval VARCHAR(8) DEFAULT NULL,
|
||||
check_timeout SMALLINT UNSIGNED DEFAULT NULL,
|
||||
enable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_active_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_passive_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_event_handler ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_flapping ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_perfdata ENUM('y', 'n') DEFAULT NULL,
|
||||
event_command VARCHAR(255) DEFAULT NULL,
|
||||
flapping_threshold_high SMALLINT UNSIGNED DEFAULT NULL,
|
||||
flapping_threshold_low SMALLINT UNSIGNED DEFAULT NULL,
|
||||
volatile ENUM('y', 'n') DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
command_endpoint VARCHAR(255) DEFAULT NULL,
|
||||
notes TEXT DEFAULT NULL,
|
||||
notes_url VARCHAR(255) DEFAULT NULL,
|
||||
action_url VARCHAR(255) DEFAULT NULL,
|
||||
icon_image VARCHAR(255) DEFAULT NULL,
|
||||
icon_image_alt VARCHAR(255) DEFAULT NULL,
|
||||
has_agent ENUM('y', 'n') DEFAULT NULL,
|
||||
master_should_connect ENUM('y', 'n') DEFAULT NULL,
|
||||
accept_config ENUM('y', 'n') DEFAULT NULL,
|
||||
api_key VARCHAR(40) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_host_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_hostgroup (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_hostgroup_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_servicegroup (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_servicegroup_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_usergroup (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_usergroup_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_user (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
email VARCHAR(255) DEFAULT NULL,
|
||||
pager VARCHAR(255) DEFAULT NULL,
|
||||
enable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
period VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
states TEXT DEFAULT NULL,
|
||||
types TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_user_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_zone (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
parent VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
is_global ENUM('y', 'n') DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_zone_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_timeperiod (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
update_method VARCHAR(64) DEFAULT NULL COMMENT 'Usually LegacyTimePeriod',
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
prefer_includes ENUM('y', 'n') DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_timeperiod_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_command (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
methods_execute VARCHAR(64) DEFAULT NULL,
|
||||
command TEXT DEFAULT NULL,
|
||||
is_string ENUM('y', 'n') NULL,
|
||||
timeout SMALLINT UNSIGNED DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
arguments TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_command_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_apiuser (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
password VARCHAR(255) DEFAULT NULL,
|
||||
client_dn VARCHAR(64) DEFAULT NULL,
|
||||
permissions TEXT DEFAULT NULL COMMENT 'JSON-encoded permissions',
|
||||
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_apiuser_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_endpoint (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'external_object') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
host VARCHAR(255) DEFAULT NULL,
|
||||
port SMALLINT UNSIGNED DEFAULT NULL,
|
||||
log_duration VARCHAR(32) DEFAULT NULL,
|
||||
apiuser VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_endpoint_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_service (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
display_name VARCHAR(255) DEFAULT NULL,
|
||||
host VARCHAR(255) DEFAULT NULL,
|
||||
service_set VARCHAR(255) DEFAULT NULL,
|
||||
check_command VARCHAR(255) DEFAULT NULL,
|
||||
max_check_attempts MEDIUMINT UNSIGNED DEFAULT NULL,
|
||||
check_period VARCHAR(255) DEFAULT NULL,
|
||||
check_interval VARCHAR(8) DEFAULT NULL,
|
||||
retry_interval VARCHAR(8) DEFAULT NULL,
|
||||
check_timeout SMALLINT UNSIGNED DEFAULT NULL,
|
||||
enable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_active_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_passive_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_event_handler ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_flapping ENUM('y', 'n') DEFAULT NULL,
|
||||
enable_perfdata ENUM('y', 'n') DEFAULT NULL,
|
||||
event_command VARCHAR(255) DEFAULT NULL,
|
||||
flapping_threshold_high SMALLINT UNSIGNED DEFAULT NULL,
|
||||
flapping_threshold_low SMALLINT UNSIGNED DEFAULT NULL,
|
||||
volatile ENUM('y', 'n') DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
command_endpoint VARCHAR(255) DEFAULT NULL,
|
||||
notes TEXT DEFAULT NULL,
|
||||
notes_url VARCHAR(255) DEFAULT NULL,
|
||||
action_url VARCHAR(255) DEFAULT NULL,
|
||||
icon_image VARCHAR(255) DEFAULT NULL,
|
||||
icon_image_alt VARCHAR(255) DEFAULT NULL,
|
||||
use_agent ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_for VARCHAR(255) DEFAULT NULL,
|
||||
use_var_overrides ENUM('y', 'n') DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
-- template_choice VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
INDEX search_object_name (object_name),
|
||||
INDEX search_display_name (display_name),
|
||||
CONSTRAINT icinga_service_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_notification (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||
host VARCHAR(255) DEFAULT NULL,
|
||||
service VARCHAR(255) DEFAULT NULL,
|
||||
times_begin INT(10) UNSIGNED DEFAULT NULL,
|
||||
times_end INT(10) UNSIGNED DEFAULT NULL,
|
||||
notification_interval INT(10) UNSIGNED DEFAULT NULL,
|
||||
command VARCHAR(255) DEFAULT NULL,
|
||||
period VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
|
||||
states TEXT DEFAULT NULL,
|
||||
types TEXT DEFAULT NULL,
|
||||
users TEXT DEFAULT NULL,
|
||||
usergroups TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
vars MEDIUMTEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_notification_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_scheduled_downtime (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
author VARCHAR(255) DEFAULT NULL,
|
||||
comment TEXT DEFAULT NULL,
|
||||
fixed ENUM('y', 'n') DEFAULT NULL,
|
||||
duration INT(10) UNSIGNED DEFAULT NULL,
|
||||
with_services ENUM('y', 'n') NULL DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_scheduled_downtime_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE branched_icinga_dependency (
|
||||
uuid VARBINARY(16) NOT NULL,
|
||||
branch_uuid VARBINARY(16) NOT NULL,
|
||||
branch_created ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
branch_deleted ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name VARCHAR(255) DEFAULT NULL,
|
||||
object_type ENUM('object', 'template', 'apply') DEFAULT NULL,
|
||||
disabled ENUM('y', 'n') DEFAULT NULL,
|
||||
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||
parent_host VARCHAR(255) DEFAULT NULL,
|
||||
parent_host_var VARCHAR(128) DEFAULT NULL,
|
||||
parent_service VARCHAR(255) DEFAULT NULL,
|
||||
child_host VARCHAR(255) DEFAULT NULL,
|
||||
child_service VARCHAR(255) DEFAULT NULL,
|
||||
disable_checks ENUM('y', 'n') DEFAULT NULL,
|
||||
disable_notifications ENUM('y', 'n') DEFAULT NULL,
|
||||
ignore_soft_states ENUM('y', 'n') DEFAULT NULL,
|
||||
period VARCHAR(255) DEFAULT NULL,
|
||||
zone VARCHAR(255) DEFAULT NULL,
|
||||
assign_filter TEXT DEFAULT NULL,
|
||||
parent_service_by_name VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
UNIQUE INDEX branch_object_name (branch_uuid, object_name),
|
||||
INDEX search_object_name (object_name),
|
||||
CONSTRAINT icinga_dependency_branch
|
||||
FOREIGN KEY branch (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO director_schema_migration
|
||||
(schema_version, migration_time)
|
||||
VALUES (173, NOW());
|
||||
VALUES (175, NOW());
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
ALTER TABLE icinga_zone ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_zone SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_zone ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX zone_uuid ON icinga_zone (uuid);
|
||||
|
||||
ALTER TABLE icinga_timeperiod ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_timeperiod SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_timeperiod ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX timeperiod_uuid ON icinga_timeperiod (uuid);
|
||||
|
||||
ALTER TABLE icinga_command ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_command SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_command ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX command_uuid ON icinga_command (uuid);
|
||||
|
||||
ALTER TABLE icinga_apiuser ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_apiuser SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_apiuser ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX apiuser_uuid ON icinga_apiuser (uuid);
|
||||
|
||||
ALTER TABLE icinga_endpoint ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_endpoint SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_endpoint ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX endpoint_uuid ON icinga_endpoint (uuid);
|
||||
|
||||
ALTER TABLE icinga_host ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_host SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_host ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX host_uuid ON icinga_host (uuid);
|
||||
|
||||
ALTER TABLE icinga_service ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_service SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_service ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX service_uuid ON icinga_service (uuid);
|
||||
|
||||
ALTER TABLE icinga_hostgroup ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_hostgroup SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_hostgroup ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX hostgroup_uuid ON icinga_hostgroup (uuid);
|
||||
|
||||
ALTER TABLE icinga_servicegroup ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_servicegroup SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_servicegroup ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX servicegroup_uuid ON icinga_servicegroup (uuid);
|
||||
|
||||
ALTER TABLE icinga_user ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_user SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_user ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX user_uuid ON icinga_user (uuid);
|
||||
|
||||
ALTER TABLE icinga_usergroup ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_usergroup SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_usergroup ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX usergroup_uuid ON icinga_usergroup (uuid);
|
||||
|
||||
ALTER TABLE icinga_notification ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_notification SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_notification ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX notification_uuid ON icinga_notification (uuid);
|
||||
|
||||
ALTER TABLE icinga_dependency ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_dependency SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_dependency ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX dependency_uuid ON icinga_dependency (uuid);
|
||||
|
||||
ALTER TABLE icinga_scheduled_downtime ADD COLUMN uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16);
|
||||
UPDATE icinga_scheduled_downtime SET uuid = decode(replace(gen_random_uuid()::text, '-', ''), 'hex') WHERE uuid IS NULL;
|
||||
ALTER TABLE icinga_scheduled_downtime ALTER COLUMN uuid SET NOT NULL;
|
||||
CREATE UNIQUE INDEX scheduled_downtime_uuid ON icinga_scheduled_downtime (uuid);
|
||||
|
||||
INSERT INTO director_schema_migration
|
||||
(schema_version, migration_time)
|
||||
VALUES (174, NOW());
|
|
@ -0,0 +1,512 @@
|
|||
CREATE TABLE director_branch (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
owner character varying(255) NOT NULL,
|
||||
branch_name character varying(255) NOT NULL,
|
||||
description text DEFAULT NULL,
|
||||
ts_merge_request bigint DEFAULT NULL,
|
||||
PRIMARY KEY(uuid)
|
||||
);
|
||||
CREATE UNIQUE INDEX branch_branch_name ON director_branch (branch_name);
|
||||
|
||||
CREATE TYPE enum_branch_action AS ENUM('create', 'modify', 'delete');
|
||||
|
||||
CREATE TABLE director_branch_activity (
|
||||
timestamp_ns bigint NOT NULL,
|
||||
object_uuid bytea NOT NULL CHECK(LENGTH(object_uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
action enum_branch_action NOT NULL,
|
||||
object_table character varying(64) NOT NULL,
|
||||
author character varying(255) NOT NULL,
|
||||
former_properties text NOT NULL,
|
||||
modified_properties text NOT NULL,
|
||||
PRIMARY KEY (timestamp_ns),
|
||||
CONSTRAINT branch_activity_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
CREATE INDEX branch_activity_object_uuid ON director_branch_activity (object_uuid);
|
||||
CREATE INDEX branch_activity_branch_uuid ON director_branch_activity (branch_uuid);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_host (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name CHARACTER VARYING(255) DEFAULT NULL,
|
||||
address character varying(255) DEFAULT NULL,
|
||||
address6 character varying(45) DEFAULT NULL,
|
||||
check_command character varying(255) DEFAULT NULL,
|
||||
max_check_attempts integer DEFAULT NULL,
|
||||
check_period character varying(255) DEFAULT NULL,
|
||||
check_interval character varying(8) DEFAULT NULL,
|
||||
retry_interval character varying(8) DEFAULT NULL,
|
||||
check_timeout smallint DEFAULT NULL,
|
||||
enable_notifications enum_boolean DEFAULT NULL,
|
||||
enable_active_checks enum_boolean DEFAULT NULL,
|
||||
enable_passive_checks enum_boolean DEFAULT NULL,
|
||||
enable_event_handler enum_boolean DEFAULT NULL,
|
||||
enable_flapping enum_boolean DEFAULT NULL,
|
||||
enable_perfdata enum_boolean DEFAULT NULL,
|
||||
event_command character varying(255) DEFAULT NULL,
|
||||
flapping_threshold_high smallint default null,
|
||||
flapping_threshold_low smallint default null,
|
||||
volatile enum_boolean DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
command_endpoint character varying(255) DEFAULT NULL,
|
||||
notes text DEFAULT NULL,
|
||||
notes_url character varying(255) DEFAULT NULL,
|
||||
action_url character varying(255) DEFAULT NULL,
|
||||
icon_image character varying(255) DEFAULT NULL,
|
||||
icon_image_alt character varying(255) DEFAULT NULL,
|
||||
has_agent enum_boolean DEFAULT NULL,
|
||||
master_should_connect enum_boolean DEFAULT NULL,
|
||||
accept_config enum_boolean DEFAULT NULL,
|
||||
api_key character varying(40) DEFAULT NULL,
|
||||
-- template_choice character varying(255) DEFAULT NULL, -- TODO: Forbid them!
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_host_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX host_branch_object_name ON branched_icinga_host (branch_uuid, object_name);
|
||||
CREATE INDEX branched_host_search_object_name ON branched_icinga_host (object_name);
|
||||
CREATE INDEX branched_host_search_display_name ON branched_icinga_host (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_hostgroup (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_hostgroup_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX hostgroup_branch_object_name ON branched_icinga_hostgroup (branch_uuid, object_name);
|
||||
CREATE INDEX branched_hostgroup_search_object_name ON branched_icinga_hostgroup (object_name);
|
||||
CREATE INDEX branched_hostgroup_search_display_name ON branched_icinga_hostgroup (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_servicegroup (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_servicegroup_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX servicegroup_branch_object_name ON branched_icinga_servicegroup (branch_uuid, object_name);
|
||||
CREATE INDEX branched_servicegroup_search_object_name ON branched_icinga_servicegroup (object_name);
|
||||
CREATE INDEX branched_servicegroup_search_display_name ON branched_icinga_servicegroup (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_usergroup (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_usergroup_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX usergroup_branch_object_name ON branched_icinga_usergroup (branch_uuid, object_name);
|
||||
CREATE INDEX branched_usergroup_search_object_name ON branched_icinga_usergroup (object_name);
|
||||
CREATE INDEX branched_usergroup_search_display_name ON branched_icinga_usergroup (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_user (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
email character varying(255) DEFAULT NULL,
|
||||
pager character varying(255) DEFAULT NULL,
|
||||
enable_notifications enum_boolean DEFAULT NULL,
|
||||
period character varying(255) DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_user_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX user_branch_object_name ON branched_icinga_user (branch_uuid, object_name);
|
||||
CREATE INDEX branched_user_search_object_name ON branched_icinga_user (object_name);
|
||||
CREATE INDEX branched_user_search_display_name ON branched_icinga_user (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_zone (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
parent character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
is_global enum_boolean DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_zone_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX zone_branch_object_name ON branched_icinga_zone (branch_uuid, object_name);
|
||||
CREATE INDEX branched_zone_search_object_name ON branched_icinga_zone (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_timeperiod (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
update_method character varying(64) DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
prefer_includes enum_boolean DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_timeperiod_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX timeperiod_branch_object_name ON branched_icinga_timeperiod (branch_uuid, object_name);
|
||||
CREATE INDEX branched_timeperiod_search_object_name ON branched_icinga_timeperiod (object_name);
|
||||
CREATE INDEX branched_timeperiod_search_display_name ON branched_icinga_timeperiod (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_command (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT NULL,
|
||||
methods_execute character varying(64) DEFAULT NULL,
|
||||
command text DEFAULT NULL,
|
||||
is_string enum_boolean DEFAULT NULL,
|
||||
-- env text DEFAULT NULL,
|
||||
timeout smallint DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
arguments TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_command_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX command_branch_object_name ON branched_icinga_command (branch_uuid, object_name);
|
||||
CREATE INDEX branched_command_search_object_name ON branched_icinga_command (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_apiuser (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name CHARACTER VARYING(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT NULL,
|
||||
password CHARACTER VARYING(255) DEFAULT NULL,
|
||||
client_dn CHARACTER VARYING(64) DEFAULT NULL,
|
||||
permissions TEXT DEFAULT NULL,
|
||||
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_apiuser_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX apiuser_branch_object_name ON branched_icinga_apiuser (branch_uuid, object_name);
|
||||
CREATE INDEX branched_apiuser_search_object_name ON branched_icinga_apiuser (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_endpoint (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT NULL,
|
||||
host character varying(255) DEFAULT NULL,
|
||||
port d_smallint DEFAULT NULL,
|
||||
log_duration character varying(32) DEFAULT NULL,
|
||||
apiuser character varying(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_endpoint_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX endpoint_branch_object_name ON branched_icinga_endpoint (branch_uuid, object_name);
|
||||
CREATE INDEX branched_endpoint_search_object_name ON branched_icinga_endpoint (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_service (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
host character varying(255) DEFAULT NULL,
|
||||
service_set character varying(255) DEFAULT NULL,
|
||||
check_command character varying(255) DEFAULT NULL,
|
||||
max_check_attempts integer DEFAULT NULL,
|
||||
check_period character varying(255) DEFAULT NULL,
|
||||
check_interval character varying(8) DEFAULT NULL,
|
||||
retry_interval character varying(8) DEFAULT NULL,
|
||||
check_timeout smallint DEFAULT NULL,
|
||||
enable_notifications enum_boolean DEFAULT NULL,
|
||||
enable_active_checks enum_boolean DEFAULT NULL,
|
||||
enable_passive_checks enum_boolean DEFAULT NULL,
|
||||
enable_event_handler enum_boolean DEFAULT NULL,
|
||||
enable_flapping enum_boolean DEFAULT NULL,
|
||||
enable_perfdata enum_boolean DEFAULT NULL,
|
||||
event_command character varying(255) DEFAULT NULL,
|
||||
flapping_threshold_high smallint DEFAULT NULL,
|
||||
flapping_threshold_low smallint DEFAULT NULL,
|
||||
volatile enum_boolean DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
command_endpoint character varying(255) DEFAULT NULL,
|
||||
notes text DEFAULT NULL,
|
||||
notes_url character varying(255) DEFAULT NULL,
|
||||
action_url character varying(255) DEFAULT NULL,
|
||||
icon_image character varying(255) DEFAULT NULL,
|
||||
icon_image_alt character varying(255) DEFAULT NULL,
|
||||
use_agent enum_boolean DEFAULT NULL,
|
||||
apply_for character varying(255) DEFAULT NULL,
|
||||
use_var_overrides enum_boolean DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
-- template_choice_id int DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_service_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX service_branch_object_name ON branched_icinga_service (branch_uuid, object_name);
|
||||
CREATE INDEX branched_service_search_object_name ON branched_icinga_service (object_name);
|
||||
CREATE INDEX branched_service_search_display_name ON branched_icinga_service (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_notification (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name CHARACTER VARYING(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
apply_to enum_host_service DEFAULT NULL,
|
||||
host character varying(255) DEFAULT NULL,
|
||||
service character varying(255) DEFAULT NULL,
|
||||
times_begin integer DEFAULT NULL,
|
||||
times_end integer DEFAULT NULL,
|
||||
notification_interval integer DEFAULT NULL,
|
||||
command character varying(255) DEFAULT NULL,
|
||||
period character varying(255) DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
|
||||
states TEXT DEFAULT NULL,
|
||||
types TEXT DEFAULT NULL,
|
||||
users TEXT DEFAULT NULL,
|
||||
usergroups TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_notification_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX notification_branch_object_name ON branched_icinga_notification (branch_uuid, object_name);
|
||||
CREATE INDEX branched_notification_search_object_name ON branched_icinga_notification (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_scheduled_downtime (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
zone_id integer DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
apply_to enum_host_service DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
author character varying(255) DEFAULT NULL,
|
||||
comment text DEFAULT NULL,
|
||||
fixed enum_boolean DEFAULT NULL,
|
||||
duration int DEFAULT NULL,
|
||||
with_services enum_boolean DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_scheduled_downtime_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX scheduled_downtime_branch_object_name ON branched_icinga_scheduled_downtime (branch_uuid, object_name);
|
||||
CREATE INDEX branched_scheduled_downtime_search_object_name ON branched_icinga_scheduled_downtime (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_dependency (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean DEFAULT 'n',
|
||||
apply_to enum_host_service NULL DEFAULT NULL,
|
||||
parent_host character varying(255) DEFAULT NULL,
|
||||
parent_host_var character varying(128) DEFAULT NULL,
|
||||
parent_service character varying(255) DEFAULT NULL,
|
||||
child_host character varying(255) DEFAULT NULL,
|
||||
child_service character varying(255) DEFAULT NULL,
|
||||
disable_checks enum_boolean DEFAULT NULL,
|
||||
disable_notifications enum_boolean DEFAULT NULL,
|
||||
ignore_soft_states enum_boolean DEFAULT NULL,
|
||||
period_id integer DEFAULT NULL,
|
||||
zone_id integer DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
parent_service_by_name character varying(255),
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_dependency_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX dependency_branch_object_name ON branched_icinga_dependency (branch_uuid, object_name);
|
||||
CREATE INDEX branched_dependency_search_object_name ON branched_icinga_dependency (object_name);
|
||||
|
||||
|
||||
INSERT INTO director_schema_migration
|
||||
(schema_version, migration_time)
|
||||
VALUES (175, NOW());
|
540
schema/pgsql.sql
540
schema/pgsql.sql
|
@ -311,6 +311,7 @@ CREATE TABLE director_setting (
|
|||
|
||||
CREATE TABLE icinga_zone (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
parent_id integer DEFAULT NULL,
|
||||
object_name character varying(255) NOT NULL UNIQUE,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
|
@ -325,6 +326,7 @@ CREATE TABLE icinga_zone (
|
|||
);
|
||||
|
||||
CREATE INDEX zone_parent ON icinga_zone (parent_id);
|
||||
CREATE UNIQUE INDEX zone_uuid ON icinga_zone (uuid);
|
||||
|
||||
|
||||
CREATE TABLE icinga_zone_inheritance (
|
||||
|
@ -351,6 +353,7 @@ CREATE INDEX zone_inheritance_zone_parent ON icinga_zone_inheritance (parent_zon
|
|||
|
||||
CREATE TABLE icinga_timeperiod (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
update_method character varying(64) DEFAULT NULL,
|
||||
|
@ -366,6 +369,7 @@ CREATE TABLE icinga_timeperiod (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX timeperiod_uuid ON icinga_timeperiod (uuid);
|
||||
CREATE UNIQUE INDEX timeperiod_object_name ON icinga_timeperiod (object_name, zone_id);
|
||||
CREATE INDEX timeperiod_zone ON icinga_timeperiod (zone_id);
|
||||
COMMENT ON COLUMN icinga_timeperiod.update_method IS 'Usually LegacyTimePeriod';
|
||||
|
@ -453,6 +457,7 @@ CREATE INDEX director_job_setting_job ON director_job_setting (job_id);
|
|||
|
||||
CREATE TABLE icinga_command (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -470,6 +475,7 @@ CREATE TABLE icinga_command (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX command_uuid ON icinga_command (uuid);
|
||||
CREATE UNIQUE INDEX command_object_name ON icinga_command (object_name);
|
||||
CREATE INDEX command_zone ON icinga_command (zone_id);
|
||||
COMMENT ON COLUMN icinga_command.object_type IS 'external_object is an attempt to work with existing commands';
|
||||
|
@ -567,6 +573,7 @@ CREATE INDEX command_var_checksum ON icinga_command_var (checksum);
|
|||
|
||||
CREATE TABLE icinga_apiuser (
|
||||
id BIGSERIAL,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name CHARACTER VARYING(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -576,11 +583,13 @@ CREATE TABLE icinga_apiuser (
|
|||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX apiuser_uuid ON icinga_apiuser (uuid);
|
||||
COMMENT ON COLUMN icinga_apiuser.permissions IS 'JSON-encoded permissions';
|
||||
|
||||
|
||||
CREATE TABLE icinga_endpoint (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
zone_id integer DEFAULT NULL,
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
|
@ -602,6 +611,7 @@ CREATE TABLE icinga_endpoint (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX endpoint_uuid ON icinga_endpoint (uuid);
|
||||
CREATE UNIQUE INDEX endpoint_object_name ON icinga_endpoint (object_name);
|
||||
CREATE INDEX endpoint_zone ON icinga_endpoint (zone_id);
|
||||
COMMENT ON COLUMN icinga_endpoint.host IS 'IP address / hostname of remote node';
|
||||
|
@ -647,6 +657,7 @@ CREATE INDEX host_template_choice_required_template ON icinga_host_template_choi
|
|||
|
||||
CREATE TABLE icinga_host (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -715,6 +726,7 @@ CREATE TABLE icinga_host (
|
|||
);
|
||||
|
||||
|
||||
CREATE UNIQUE INDEX host_uuid ON icinga_host (uuid);
|
||||
CREATE UNIQUE INDEX object_name_host ON icinga_host (object_name, zone_id);
|
||||
CREATE UNIQUE INDEX host_api_key ON icinga_host (api_key);
|
||||
CREATE INDEX host_zone ON icinga_host (zone_id);
|
||||
|
@ -834,6 +846,7 @@ CREATE INDEX service_template_choice_required_template ON icinga_service_templat
|
|||
|
||||
CREATE TABLE icinga_service (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean DEFAULT 'n',
|
||||
|
@ -912,6 +925,7 @@ CREATE TABLE icinga_service (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX service_uuid ON icinga_service (uuid);
|
||||
CREATE INDEX service_zone ON icinga_service (zone_id);
|
||||
CREATE INDEX service_timeperiod ON icinga_service (check_period_id);
|
||||
CREATE INDEX service_check_command ON icinga_service (check_command_id);
|
||||
|
@ -1076,6 +1090,7 @@ CREATE INDEX service_set_var_checksum ON icinga_service_set_var (checksum);
|
|||
|
||||
CREATE TABLE icinga_hostgroup (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -1084,6 +1099,7 @@ CREATE TABLE icinga_hostgroup (
|
|||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX hostgroup_uuid ON icinga_hostgroup (uuid);
|
||||
CREATE UNIQUE INDEX hostgroup_object_name ON icinga_hostgroup (object_name);
|
||||
CREATE INDEX hostgroup_search_idx ON icinga_hostgroup (display_name);
|
||||
|
||||
|
@ -1113,6 +1129,7 @@ CREATE INDEX hostgroup_inheritance_hostgroup_parent ON icinga_hostgroup_inherita
|
|||
|
||||
CREATE TABLE icinga_servicegroup (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -1121,6 +1138,7 @@ CREATE TABLE icinga_servicegroup (
|
|||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX servicegroup_uuid ON icinga_servicegroup (uuid);
|
||||
CREATE UNIQUE INDEX servicegroup_object_name ON icinga_servicegroup (object_name);
|
||||
CREATE INDEX servicegroup_search_idx ON icinga_servicegroup (display_name);
|
||||
|
||||
|
@ -1248,6 +1266,7 @@ CREATE INDEX hostgroup_parent_parent ON icinga_hostgroup_parent (parent_hostgrou
|
|||
|
||||
CREATE TABLE icinga_user (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -1270,6 +1289,7 @@ CREATE TABLE icinga_user (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX user_uuid ON icinga_user (uuid);
|
||||
CREATE UNIQUE INDEX user_object_name ON icinga_user (object_name, zone_id);
|
||||
CREATE INDEX user_zone ON icinga_user (zone_id);
|
||||
|
||||
|
@ -1373,6 +1393,7 @@ COMMENT ON COLUMN icinga_user_field.user_id IS 'Makes only sense for templates';
|
|||
|
||||
CREATE TABLE icinga_usergroup (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -1386,6 +1407,7 @@ CREATE TABLE icinga_usergroup (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX usergroup_uuid ON icinga_usergroup (uuid);
|
||||
CREATE UNIQUE INDEX usergroup_search_idx ON icinga_usergroup (display_name);
|
||||
CREATE INDEX usergroup_object_name ON icinga_usergroup (object_name);
|
||||
CREATE INDEX usergroup_zone ON icinga_usergroup (zone_id);
|
||||
|
@ -1455,6 +1477,7 @@ CREATE INDEX usergroup_parent_parent ON icinga_usergroup_parent (parent_usergrou
|
|||
|
||||
CREATE TABLE icinga_notification (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name CHARACTER VARYING(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
@ -1496,6 +1519,8 @@ CREATE TABLE icinga_notification (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX notification_uuid ON icinga_notification (uuid);
|
||||
|
||||
|
||||
CREATE TABLE icinga_notification_user (
|
||||
notification_id integer NOT NULL,
|
||||
|
@ -2004,6 +2029,7 @@ CREATE INDEX user_resolved_var_schecksum ON icinga_user_resolved_var (checksum);
|
|||
|
||||
CREATE TABLE icinga_dependency (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean DEFAULT 'n',
|
||||
|
@ -2053,6 +2079,7 @@ CREATE TABLE icinga_dependency (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX dependency_uuid ON icinga_dependency (uuid);
|
||||
CREATE INDEX dependency_parent_host ON icinga_dependency (parent_host_id);
|
||||
CREATE INDEX dependency_parent_service ON icinga_dependency (parent_service_id);
|
||||
CREATE INDEX dependency_child_host ON icinga_dependency (child_host_id);
|
||||
|
@ -2133,6 +2160,7 @@ CREATE TABLE icinga_timeperiod_exclude (
|
|||
|
||||
CREATE TABLE icinga_scheduled_downtime (
|
||||
id serial,
|
||||
uuid bytea UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
object_name character varying(255) NOT NULL,
|
||||
zone_id integer DEFAULT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
|
@ -2152,6 +2180,7 @@ CREATE TABLE icinga_scheduled_downtime (
|
|||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX scheduled_downtime_uuid ON icinga_scheduled_downtime (uuid);
|
||||
CREATE UNIQUE INDEX scheduled_downtime_object_name ON icinga_scheduled_downtime (object_name);
|
||||
CREATE INDEX scheduled_downtime_zone ON icinga_scheduled_downtime (zone_id);
|
||||
|
||||
|
@ -2199,6 +2228,515 @@ COMMENT ON COLUMN icinga_scheduled_downtime_range.range_type IS 'include -> rang
|
|||
COMMENT ON COLUMN icinga_scheduled_downtime_range.merge_behaviour IS 'set -> = {}, add -> += {}, substract -> -= {}';
|
||||
|
||||
|
||||
CREATE TABLE director_branch (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
owner character varying(255) NOT NULL,
|
||||
branch_name character varying(255) NOT NULL,
|
||||
description text DEFAULT NULL,
|
||||
ts_merge_request bigint DEFAULT NULL,
|
||||
PRIMARY KEY(uuid)
|
||||
);
|
||||
CREATE UNIQUE INDEX branch_branch_name ON director_branch (branch_name);
|
||||
|
||||
CREATE TYPE enum_branch_action AS ENUM('create', 'modify', 'delete');
|
||||
|
||||
CREATE TABLE director_branch_activity (
|
||||
timestamp_ns bigint NOT NULL,
|
||||
object_uuid bytea NOT NULL CHECK(LENGTH(object_uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
action enum_branch_action NOT NULL,
|
||||
object_table character varying(64) NOT NULL,
|
||||
author character varying(255) NOT NULL,
|
||||
former_properties text NOT NULL,
|
||||
modified_properties text NOT NULL,
|
||||
PRIMARY KEY (timestamp_ns),
|
||||
CONSTRAINT branch_activity_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
CREATE INDEX branch_activity_object_uuid ON director_branch_activity (object_uuid);
|
||||
CREATE INDEX branch_activity_branch_uuid ON director_branch_activity (branch_uuid);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_host (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name CHARACTER VARYING(255) DEFAULT NULL,
|
||||
address character varying(255) DEFAULT NULL,
|
||||
address6 character varying(45) DEFAULT NULL,
|
||||
check_command character varying(255) DEFAULT NULL,
|
||||
max_check_attempts integer DEFAULT NULL,
|
||||
check_period character varying(255) DEFAULT NULL,
|
||||
check_interval character varying(8) DEFAULT NULL,
|
||||
retry_interval character varying(8) DEFAULT NULL,
|
||||
check_timeout smallint DEFAULT NULL,
|
||||
enable_notifications enum_boolean DEFAULT NULL,
|
||||
enable_active_checks enum_boolean DEFAULT NULL,
|
||||
enable_passive_checks enum_boolean DEFAULT NULL,
|
||||
enable_event_handler enum_boolean DEFAULT NULL,
|
||||
enable_flapping enum_boolean DEFAULT NULL,
|
||||
enable_perfdata enum_boolean DEFAULT NULL,
|
||||
event_command character varying(255) DEFAULT NULL,
|
||||
flapping_threshold_high smallint default null,
|
||||
flapping_threshold_low smallint default null,
|
||||
volatile enum_boolean DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
command_endpoint character varying(255) DEFAULT NULL,
|
||||
notes text DEFAULT NULL,
|
||||
notes_url character varying(255) DEFAULT NULL,
|
||||
action_url character varying(255) DEFAULT NULL,
|
||||
icon_image character varying(255) DEFAULT NULL,
|
||||
icon_image_alt character varying(255) DEFAULT NULL,
|
||||
has_agent enum_boolean DEFAULT NULL,
|
||||
master_should_connect enum_boolean DEFAULT NULL,
|
||||
accept_config enum_boolean DEFAULT NULL,
|
||||
api_key character varying(40) DEFAULT NULL,
|
||||
-- template_choice character varying(255) DEFAULT NULL, -- TODO: Forbid them!
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_host_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX host_branch_object_name ON branched_icinga_host (branch_uuid, object_name);
|
||||
CREATE INDEX branched_host_search_object_name ON branched_icinga_host (object_name);
|
||||
CREATE INDEX branched_host_search_display_name ON branched_icinga_host (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_hostgroup (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_hostgroup_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX hostgroup_branch_object_name ON branched_icinga_hostgroup (branch_uuid, object_name);
|
||||
CREATE INDEX branched_hostgroup_search_object_name ON branched_icinga_hostgroup (object_name);
|
||||
CREATE INDEX branched_hostgroup_search_display_name ON branched_icinga_hostgroup (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_servicegroup (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_servicegroup_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX servicegroup_branch_object_name ON branched_icinga_servicegroup (branch_uuid, object_name);
|
||||
CREATE INDEX branched_servicegroup_search_object_name ON branched_icinga_servicegroup (object_name);
|
||||
CREATE INDEX branched_servicegroup_search_display_name ON branched_icinga_servicegroup (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_usergroup (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_usergroup_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX usergroup_branch_object_name ON branched_icinga_usergroup (branch_uuid, object_name);
|
||||
CREATE INDEX branched_usergroup_search_object_name ON branched_icinga_usergroup (object_name);
|
||||
CREATE INDEX branched_usergroup_search_display_name ON branched_icinga_usergroup (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_user (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
email character varying(255) DEFAULT NULL,
|
||||
pager character varying(255) DEFAULT NULL,
|
||||
enable_notifications enum_boolean DEFAULT NULL,
|
||||
period character varying(255) DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_user_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX user_branch_object_name ON branched_icinga_user (branch_uuid, object_name);
|
||||
CREATE INDEX branched_user_search_object_name ON branched_icinga_user (object_name);
|
||||
CREATE INDEX branched_user_search_display_name ON branched_icinga_user (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_zone (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
parent character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
is_global enum_boolean DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_zone_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX zone_branch_object_name ON branched_icinga_zone (branch_uuid, object_name);
|
||||
CREATE INDEX branched_zone_search_object_name ON branched_icinga_zone (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_timeperiod (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
update_method character varying(64) DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
prefer_includes enum_boolean DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_timeperiod_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX timeperiod_branch_object_name ON branched_icinga_timeperiod (branch_uuid, object_name);
|
||||
CREATE INDEX branched_timeperiod_search_object_name ON branched_icinga_timeperiod (object_name);
|
||||
CREATE INDEX branched_timeperiod_search_display_name ON branched_icinga_timeperiod (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_command (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT NULL,
|
||||
methods_execute character varying(64) DEFAULT NULL,
|
||||
command text DEFAULT NULL,
|
||||
is_string enum_boolean DEFAULT NULL,
|
||||
-- env text DEFAULT NULL,
|
||||
timeout smallint DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
arguments TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_command_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX command_branch_object_name ON branched_icinga_command (branch_uuid, object_name);
|
||||
CREATE INDEX branched_command_search_object_name ON branched_icinga_command (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_apiuser (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name CHARACTER VARYING(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT NULL,
|
||||
password CHARACTER VARYING(255) DEFAULT NULL,
|
||||
client_dn CHARACTER VARYING(64) DEFAULT NULL,
|
||||
permissions TEXT DEFAULT NULL,
|
||||
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_apiuser_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX apiuser_branch_object_name ON branched_icinga_apiuser (branch_uuid, object_name);
|
||||
CREATE INDEX branched_apiuser_search_object_name ON branched_icinga_apiuser (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_endpoint (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean NOT NULL DEFAULT NULL,
|
||||
host character varying(255) DEFAULT NULL,
|
||||
port d_smallint DEFAULT NULL,
|
||||
log_duration character varying(32) DEFAULT NULL,
|
||||
apiuser character varying(255) DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_endpoint_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX endpoint_branch_object_name ON branched_icinga_endpoint (branch_uuid, object_name);
|
||||
CREATE INDEX branched_endpoint_search_object_name ON branched_icinga_endpoint (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_service (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
display_name character varying(255) DEFAULT NULL,
|
||||
host character varying(255) DEFAULT NULL,
|
||||
service_set character varying(255) DEFAULT NULL,
|
||||
check_command character varying(255) DEFAULT NULL,
|
||||
max_check_attempts integer DEFAULT NULL,
|
||||
check_period character varying(255) DEFAULT NULL,
|
||||
check_interval character varying(8) DEFAULT NULL,
|
||||
retry_interval character varying(8) DEFAULT NULL,
|
||||
check_timeout smallint DEFAULT NULL,
|
||||
enable_notifications enum_boolean DEFAULT NULL,
|
||||
enable_active_checks enum_boolean DEFAULT NULL,
|
||||
enable_passive_checks enum_boolean DEFAULT NULL,
|
||||
enable_event_handler enum_boolean DEFAULT NULL,
|
||||
enable_flapping enum_boolean DEFAULT NULL,
|
||||
enable_perfdata enum_boolean DEFAULT NULL,
|
||||
event_command character varying(255) DEFAULT NULL,
|
||||
flapping_threshold_high smallint DEFAULT NULL,
|
||||
flapping_threshold_low smallint DEFAULT NULL,
|
||||
volatile enum_boolean DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
command_endpoint character varying(255) DEFAULT NULL,
|
||||
notes text DEFAULT NULL,
|
||||
notes_url character varying(255) DEFAULT NULL,
|
||||
action_url character varying(255) DEFAULT NULL,
|
||||
icon_image character varying(255) DEFAULT NULL,
|
||||
icon_image_alt character varying(255) DEFAULT NULL,
|
||||
use_agent enum_boolean DEFAULT NULL,
|
||||
apply_for character varying(255) DEFAULT NULL,
|
||||
use_var_overrides enum_boolean DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
-- template_choice_id int DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
groups TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_service_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX service_branch_object_name ON branched_icinga_service (branch_uuid, object_name);
|
||||
CREATE INDEX branched_service_search_object_name ON branched_icinga_service (object_name);
|
||||
CREATE INDEX branched_service_search_display_name ON branched_icinga_service (display_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_notification (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name CHARACTER VARYING(255) DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
apply_to enum_host_service DEFAULT NULL,
|
||||
host character varying(255) DEFAULT NULL,
|
||||
service character varying(255) DEFAULT NULL,
|
||||
times_begin integer DEFAULT NULL,
|
||||
times_end integer DEFAULT NULL,
|
||||
notification_interval integer DEFAULT NULL,
|
||||
command character varying(255) DEFAULT NULL,
|
||||
period character varying(255) DEFAULT NULL,
|
||||
zone character varying(255) DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
|
||||
states TEXT DEFAULT NULL,
|
||||
types TEXT DEFAULT NULL,
|
||||
users TEXT DEFAULT NULL,
|
||||
usergroups TEXT DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
vars TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_notification_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX notification_branch_object_name ON branched_icinga_notification (branch_uuid, object_name);
|
||||
CREATE INDEX branched_notification_search_object_name ON branched_icinga_notification (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_scheduled_downtime (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) DEFAULT NULL,
|
||||
zone_id integer DEFAULT NULL,
|
||||
object_type enum_object_type_all DEFAULT NULL,
|
||||
disabled enum_boolean DEFAULT NULL,
|
||||
apply_to enum_host_service DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
author character varying(255) DEFAULT NULL,
|
||||
comment text DEFAULT NULL,
|
||||
fixed enum_boolean DEFAULT NULL,
|
||||
duration int DEFAULT NULL,
|
||||
with_services enum_boolean DEFAULT NULL,
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
ranges TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_scheduled_downtime_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX scheduled_downtime_branch_object_name ON branched_icinga_scheduled_downtime (branch_uuid, object_name);
|
||||
CREATE INDEX branched_scheduled_downtime_search_object_name ON branched_icinga_scheduled_downtime (object_name);
|
||||
|
||||
|
||||
CREATE TABLE branched_icinga_dependency (
|
||||
uuid bytea NOT NULL UNIQUE CHECK(LENGTH(uuid) = 16),
|
||||
branch_uuid bytea NOT NULL CHECK(LENGTH(branch_uuid) = 16),
|
||||
branch_created enum_boolean NOT NULL DEFAULT 'n',
|
||||
branch_deleted enum_boolean NOT NULL DEFAULT 'n',
|
||||
|
||||
object_name character varying(255) NOT NULL,
|
||||
object_type enum_object_type_all NOT NULL,
|
||||
disabled enum_boolean DEFAULT 'n',
|
||||
apply_to enum_host_service NULL DEFAULT NULL,
|
||||
parent_host character varying(255) DEFAULT NULL,
|
||||
parent_host_var character varying(128) DEFAULT NULL,
|
||||
parent_service character varying(255) DEFAULT NULL,
|
||||
child_host character varying(255) DEFAULT NULL,
|
||||
child_service character varying(255) DEFAULT NULL,
|
||||
disable_checks enum_boolean DEFAULT NULL,
|
||||
disable_notifications enum_boolean DEFAULT NULL,
|
||||
ignore_soft_states enum_boolean DEFAULT NULL,
|
||||
period_id integer DEFAULT NULL,
|
||||
zone_id integer DEFAULT NULL,
|
||||
assign_filter text DEFAULT NULL,
|
||||
parent_service_by_name character varying(255),
|
||||
|
||||
imports TEXT DEFAULT NULL,
|
||||
set_null TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (branch_uuid, uuid),
|
||||
CONSTRAINT icinga_dependency_branch
|
||||
FOREIGN KEY (branch_uuid)
|
||||
REFERENCES director_branch (uuid)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX dependency_branch_object_name ON branched_icinga_dependency (branch_uuid, object_name);
|
||||
CREATE INDEX branched_dependency_search_object_name ON branched_icinga_dependency (object_name);
|
||||
|
||||
|
||||
INSERT INTO director_schema_migration
|
||||
(schema_version, migration_time)
|
||||
VALUES (173, NOW());
|
||||
VALUES (175, NOW());
|
||||
|
|
Loading…
Reference in New Issue