SelfService: controller, form, admin dashlet

refs #486
This commit is contained in:
Thomas Gelf 2017-07-06 15:11:57 +02:00
parent 15e793e3e7
commit 4fe2b0e541
3 changed files with 229 additions and 0 deletions

View File

@ -0,0 +1,68 @@
<?php
namespace Icinga\Module\Director\Controllers;
use Icinga\Module\Director\Forms\IcingaHostSelfServiceForm;
use Icinga\Module\Director\Web\Controller\ActionController;
use ipl\Html\Html;
class SelfServiceController extends ActionController
{
protected $isApified = true;
protected $requiresAuthentication = false;
protected function assertApiPermission()
{
// no permission required, we'll check the API key
}
protected function checkDirectorPermissions()
{
}
public function registerHostAction()
{
$form = IcingaHostSelfServiceForm::create($this->db());
if ($key = $this->params->get('key')) {
$form->loadTemplateWithApiKey($key);
}
if ($name = $this->params->get('name')) {
$form->setHostName($name);
}
$form->handleRequest();
if ($this->getRequest()->isApiRequest()) {
if ($newKey = $form->getHostApiKey()) {
$this->sendJson($this->getResponse(), $newKey);
} else {
$error = implode('; ', $form->getErrorMessages());
if ($error === '') {
foreach ($form->getErrors() as $elName => $errors) {
if (in_array('isEmpty', $errors)) {
$this->sendJsonError(
$this->getResponse(),
sprintf("%s is required", $elName)
);
return;
} else {
$this->sendJsonError($this->getResponse(), 'An unknown error ocurred');
}
}
} else {
$this->sendJsonError($this->getResponse(), $error);
}
}
return;
}
$this->addSingleTab($this->translate('Self Service'))
->addTitle($this->translate('Self Service - Host Registration'))
->content()->add(Html::p($this->translate(
'In case an Icinga Admin provided you with a self service API'
. ' token, this is where you can register new hosts'
)))
->add($form);
}
}

View File

@ -0,0 +1,130 @@
<?php
namespace Icinga\Module\Director\Forms;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\IcingaHost;
use Icinga\Module\Director\Web\Form\DirectorForm;
use Icinga\Security\SecurityException;
class IcingaHostSelfServiceForm extends DirectorForm
{
/** @var string */
private $hostApiKey;
/** @var IcingaHost */
private $template;
private $hostName;
public function setup()
{
if ($this->hostName === null) {
$this->addElement('text', 'object_name', array(
'label' => $this->translate('Host name'),
'required' => true,
'value' => $this->hostName,
));
}
$this->addElement('text', 'display_name', array(
'label' => $this->translate('Alias'),
));
$this->addElement('text', 'address', array(
'label' => $this->translate('Host address'),
'description' => $this->translate(
'Host address. Usually an IPv4 address, but may be any kind of address'
. ' your check plugin is able to deal with'
)
));
$this->addElement('text', 'address6', array(
'label' => $this->translate('IPv6 address'),
'description' => $this->translate('Usually your hosts main IPv6 address')
));
if ($this->template === null) {
$this->addElement('text', 'key', array(
'label' => $this->translate('API Key'),
'ignore' => true,
'required' => true,
));
}
$this->submitLabel = sprintf(
$this->translate('Register')
);
}
public function setHostName($name)
{
$this->hostName = $name;
$this->removeElement('object_name');
return $this;
}
public function loadTemplateWithApiKey($key)
{
$this->template = IcingaHost::loadWithApiKey($key, $this->getDb());
if (! $this->template->isTemplate()) {
throw new NotFoundError('Got invalid API key "%s"', $key);
}
$this->removeElement('key');
return $this->template;
}
public function onSuccess()
{
$db = $this->getDb();
if ($this->template === null) {
$this->loadTemplateWithApiKey($this->getValue('key'));
}
$name = $this->hostName ?: $this->getValue('object_name');
if (IcingaHost::exists($name, $db)) {
$host = IcingaHost::load($name, $db);
if ($host->isTemplate()) {
throw new SecurityException(
'You are not allowed to create "%s"',
$name
);
}
if (null !== $host->getProperty('api_key')) {
throw new SecurityException(
'The host "%s" has already been registered',
$name
);
}
$propertyNames = ['display_name', 'address', 'address6'];
foreach ($propertyNames as $property) {
$host->set($property, $this->getValue($property));
}
} else {
$host = IcingaHost::create(array_filter($this->getValues(), 'strlen'), $db);
$host->set('object_name', $name);
$host->set('object_type', 'object');
$host->set('imports', [$this->template]);
}
$key = $host->generateApiKey();
$host->store($db);
$this->hostApiKey = $key;
}
/**
* @return string|null
*/
public function getHostApiKey()
{
return $this->hostApiKey;
}
public static function create(Db $db)
{
return static::load()->setDb($db);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Icinga\Module\Director\Dashboard\Dashlet;
class SelfServiceDashlet extends Dashlet
{
protected $icon = 'chat';
public function getTitle()
{
return $this->translate('Self Service API');
}
public function getSummary()
{
return $this->translate(
'Icinga Director offers a Self Service API, allowing new Icinga'
. ' nodes to register themselves'
);
}
public function getUrl()
{
return 'director/settings/self-service';
}
public function listRequiredPermissions()
{
return array('director/admin');
}
}