Datalist: fix snapshot diff

fixes #2791
This commit is contained in:
Thomas Gelf 2023-08-25 17:15:08 +02:00
parent 5298243d94
commit fc7bfe7db9
4 changed files with 32 additions and 37 deletions

View File

@ -34,6 +34,10 @@ This version hasn't been released yet
* FIX: synchronizing Service (and -Set) Templates has been fixed (#2745, #2217)
* FIX: null properties with Sync policy "ignore" are now being ignored (#2657)
# Configuration Baskets
* FEATURE: it's now possible to upload snapshots for existing baskets (#1952)
* FIX: basket now shows where to expect changes for lists from snapshots (#2791)
### REST API
* FIX: Commands give 304 w/o ghost changes for same properties (#2660)

View File

@ -304,16 +304,7 @@ class Exporter
protected function exportDatalistEntries(DirectorDatalist $list)
{
$entries = [];
$id = $list->get('id');
if ($id === null) {
return $entries;
}
$dbEntries = DirectorDatalistEntry::loadAllForList($list);
// Hint: they are loaded with entry_name key
ksort($dbEntries);
foreach ($dbEntries as $entry) {
foreach ($list->getEntries() as $name => $entry) {
if ($entry->shouldBeRemoved()) {
continue;
}

View File

@ -6,6 +6,7 @@ use gipfl\Json\JsonString;
use Icinga\Module\Director\Data\Exporter;
use Icinga\Module\Director\Data\ObjectImporter;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\DirectorDatalist;
use Ramsey\Uuid\UuidInterface;
use stdClass;

View File

@ -4,7 +4,7 @@ namespace Icinga\Module\Director\Objects;
use Exception;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\DataType\DataTypeDatalist;
use Icinga\Module\Director\DirectorObject\Automation\ExportInterface;
use Icinga\Module\Director\Exception\DuplicateKeyException;
@ -23,16 +23,16 @@ class DirectorDatalist extends DbObject implements ExportInterface
];
/** @var DirectorDatalistEntry[] */
protected $storedEntries;
protected $entries;
public function getUniqueIdentifier()
{
return $this->get('list_name');
}
public function setEntries($entries)
public function setEntries($entries): void
{
$existing = $this->getStoredEntries();
$existing = $this->getEntries();
$new = [];
$seen = [];
@ -68,15 +68,13 @@ class DirectorDatalist extends DbObject implements ExportInterface
$this->hasBeenModified = true;
}
$this->storedEntries = $existing;
ksort($this->storedEntries);
return $this;
$this->entries = $existing;
ksort($this->entries);
}
protected function beforeDelete()
{
if ($this->hasBeenUsed()) {
if ($this->isInUse()) {
throw new Exception(
sprintf(
"Cannot delete '%s', as the datalist '%s' is currently being used.",
@ -87,9 +85,13 @@ class DirectorDatalist extends DbObject implements ExportInterface
}
}
protected function hasBeenUsed()
protected function isInUse(): bool
{
$datalistType = 'Icinga\\Module\\Director\\DataType\\DataTypeDatalist';
$id = $this->get('id');
if ($id === null) {
return false;
}
$db = $this->getDb();
$dataFieldsCheck = $db->select()
@ -104,8 +106,8 @@ class DirectorDatalist extends DbObject implements ExportInterface
'l.id = dfs.setting_value',
[]
)
->where('datatype = ?', $datalistType)
->where('setting_value = ?', $this->get('id'));
->where('datatype = ?', DataTypeDatalist::class)
->where('setting_value = ?', $id);
if ($db->fetchOne($dataFieldsCheck)) {
return true;
@ -114,7 +116,7 @@ class DirectorDatalist extends DbObject implements ExportInterface
$syncCheck = $db->select()
->from(['sp' =>'sync_property'], ['source_expression'])
->where('sp.destination_field = ?', 'list_id')
->where('sp.source_expression = ?', $this->get('id'));
->where('sp.source_expression = ?', $id);
if ($db->fetchOne($syncCheck)) {
return true;
@ -128,41 +130,38 @@ class DirectorDatalist extends DbObject implements ExportInterface
*/
public function onStore()
{
if ($this->storedEntries) {
if ($this->entries) {
$db = $this->getConnection();
$removedKeys = [];
$myId = $this->get('id');
foreach ($this->storedEntries as $key => $entry) {
foreach ($this->entries as $key => $entry) {
if ($entry->shouldBeRemoved()) {
$entry->delete();
$removedKeys[] = $key;
} else {
if (! $entry->hasBeenLoadedFromDb()) {
$entry->set('list_id', $myId);
}
$entry->set('list_id', $myId);
$entry->store($db);
}
}
foreach ($removedKeys as $key) {
unset($this->storedEntries[$key]);
unset($this->entries[$key]);
}
}
}
protected function getStoredEntries()
public function getEntries(): array
{
if ($this->storedEntries === null) {
if ($id = $this->get('id')) {
$this->storedEntries = DirectorDatalistEntry::loadAllForList($this);
ksort($this->storedEntries);
if ($this->entries === null) {
if ($this->get('id')) {
$this->entries = DirectorDatalistEntry::loadAllForList($this);
ksort($this->entries);
} else {
$this->storedEntries = [];
$this->entries = [];
}
}
return $this->storedEntries;
return $this->entries;
}
}