IcingaUser: add basket support

fixes #2328
This commit is contained in:
Thomas Gelf 2021-07-15 19:11:20 +02:00
parent e72da4cac4
commit 7f16d648cc
6 changed files with 132 additions and 1 deletions

View File

@ -10,4 +10,9 @@ class UserController extends ObjectController
{
$this->assertPermission('director/users');
}
protected function hasBasketSupport()
{
return true;
}
}

View File

@ -24,6 +24,9 @@ class BasketForm extends DirectorObjectForm
'IcingaTemplateChoiceService' => $this->translate('Service Template Choice'),
'ServiceTemplate' => $this->translate('Service Templates'),
'ServiceSet' => $this->translate('Service Sets'),
'UserGroup' => $this->translate('User Groups'),
'UserTemplate' => $this->translate('User Templates'),
'User' => $this->translate('Users'),
'NotificationTemplate' => $this->translate('Notification Templates'),
'Notification' => $this->translate('Notifications'),
'TimePeriod' => $this->translate('Time Periods'),

View File

@ -18,6 +18,7 @@ next (will be 1.9.0)
### Configuration Baskets
* FIX: Notification Apply Rules have not been exported (#2335)
* FEATURE: it's now possible to purge objects of specific types (#2201)
* FEATURE: exporting Users, User-Templates and -Groups is now possible (#2328)
### Permissions and Restrictions
* FEATURE: allow using monitoring module permissions (#2304)

View File

@ -20,6 +20,8 @@ use Icinga\Module\Director\Objects\IcingaServiceSet;
use Icinga\Module\Director\Objects\IcingaTemplateChoiceHost;
use Icinga\Module\Director\Objects\IcingaTemplateChoiceService;
use Icinga\Module\Director\Objects\IcingaTimePeriod;
use Icinga\Module\Director\Objects\IcingaUser;
use Icinga\Module\Director\Objects\IcingaUserGroup;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Objects\SyncRule;
use InvalidArgumentException;
@ -40,6 +42,9 @@ class BasketSnapshot extends DbObject
'IcingaTemplateChoiceService' => IcingaTemplateChoiceService::class,
'ServiceTemplate' => IcingaService::class,
'ServiceSet' => IcingaServiceSet::class,
'UserGroup' => IcingaUserGroup::class,
'UserTemplate' => [IcingaUser::class, ['object_type' => 'template']],
'User' => [IcingaUser::class, ['object_type' => 'object']],
'NotificationTemplate' => IcingaNotification::class,
'Notification' => [IcingaNotification::class, ['object_type' => 'apply']],
'DataList' => DirectorDatalist::class,
@ -73,6 +78,9 @@ class BasketSnapshot extends DbObject
'IcingaTemplateChoiceService',
'ServiceTemplate',
'ServiceSet',
'UserGroup',
'UserTemplate',
'User',
'NotificationTemplate',
'Notification',
'Dependency',

View File

@ -2,7 +2,11 @@
namespace Icinga\Module\Director\Objects;
class IcingaUser extends IcingaObject
use Icinga\Module\Director\Db;
use Icinga\Module\Director\DirectorObject\Automation\ExportInterface;
use Icinga\Module\Director\Exception\DuplicateKeyException;
class IcingaUser extends IcingaObject implements ExportInterface
{
protected $table = 'icinga_user';
@ -40,4 +44,46 @@ class IcingaUser extends IcingaObject
'period' => 'IcingaTimePeriod',
'zone' => 'IcingaZone',
);
public function export()
{
return ImportExportHelper::simpleExport($this);
}
/**
* @param $plain
* @param Db $db
* @param bool $replace
* @return IcingaUser
* @throws DuplicateKeyException
* @throws \Icinga\Exception\NotFoundError
*/
public static function import($plain, Db $db, $replace = false)
{
$properties = (array) $plain;
$key = $properties['object_name'];
if ($replace && static::exists($key, $db)) {
$object = static::load($key, $db);
} elseif (static::exists($key, $db)) {
throw new DuplicateKeyException(
'Cannot import, %s "%s" already exists',
static::create([])->getShortTableName(),
$key
);
} else {
$object = static::create([], $db);
}
// $object->newFields = $properties['fields'];
unset($properties['fields']);
$object->setProperties($properties);
return $object;
}
public function getUniqueIdentifier()
{
return $this->getObjectName();
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace Icinga\Module\Director\Objects;
use Icinga\Module\Director\Db;
/**
* Helper class, allows to reduce duplicate code. Might be moved elsewhere
* afterwards
*/
class ImportExportHelper
{
/**
* Does not support every type out of the box
*
* @param IcingaObject $object
* @return object
* @throws \Icinga\Exception\NotFoundError
*/
public static function simpleExport(IcingaObject $object)
{
$props = (array) $object->toPlainObject();
$props['fields'] = static::fetchFields($object);
ksort($props); // TODO: ksort in toPlainObject?
return (object) $props;
}
public static function fetchFields(IcingaObject $object)
{
return static::loadFieldReferences(
$object->getConnection(),
$object->getShortTableName(),
$object->get('id')
);
}
/**
* @param Db $connection
* @param string $type Warning: this will not be validated.
* @param int $id
* @return array
*/
public static function loadFieldReferences(Db $connection, $type, $id)
{
$db = $connection->getDbAdapter();
$res = $db->fetchAll(
$db->select()->from([
'f' => "icinga_${type}_field"
], [
'f.datafield_id',
'f.is_required',
'f.var_filter',
])->join(['df' => 'director_datafield'], 'df.id = f.datafield_id', [])
->where("${type}_id = ?", $id)
->order('varname ASC')
);
if (empty($res)) {
return [];
}
foreach ($res as $field) {
$field->datafield_id = (int) $field->datafield_id;
}
return $res;
}
}