Basket: add UploadForm

fixes #1731
This commit is contained in:
Thomas Gelf 2018-12-10 15:36:59 +01:00
parent b00af91059
commit b67e0c0017
4 changed files with 196 additions and 2 deletions

View File

@ -15,6 +15,7 @@ use Icinga\Module\Director\DirectorObject\Automation\BasketSnapshotFieldResolver
use Icinga\Module\Director\Forms\AddToBasketForm;
use Icinga\Module\Director\Forms\BasketCreateSnapshotForm;
use Icinga\Module\Director\Forms\BasketForm;
use Icinga\Module\Director\Forms\BasketUploadForm;
use Icinga\Module\Director\Forms\RestoreBasketForm;
use Icinga\Module\Director\Web\Controller\ActionController;
use dipl\Html\Html;
@ -106,6 +107,24 @@ class BasketController extends ActionController
$this->content()->add($form);
}
public function uploadAction()
{
$this->actions()->add(
Link::create(
$this->translate('back'),
'director/baskets',
null,
['class' => 'icon-left-big']
)
);
$this->addSingleTab($this->translate('Upload a Basket'));
$this->addTitle($this->translate('Upload a Configuration Basket'));
$form = (new BasketUploadForm())
->setDb($this->db())
->handleRequest();
$this->content()->add($form);
}
/**
* @throws \Icinga\Exception\NotFoundError
*/
@ -157,6 +176,15 @@ class BasketController extends ActionController
if ($this->params->get('action') === 'download') {
$this->getResponse()->setHeader('Content-Type', 'application/json', true);
$this->getResponse()->setHeader('Content-Disposition', sprintf(
'attachment; filename=Director-Basket_%s_%s.json',
str_replace([' ', '"'], ['_', '_'], iconv(
'UTF-8',
'ISO-8859-11//IGNORE',
$basket->get('basket_name')
)),
substr($snapSum, 0, 7)
));
echo $snapshot->getJsonDump();
return;
}

View File

@ -9,7 +9,7 @@ use Icinga\Module\Director\Web\Table\BasketTable;
class BasketsController extends ActionController
{
protected $isApified = true;
protected $isApified = false;
public function indexAction()
{
@ -21,7 +21,13 @@ class BasketsController extends ActionController
'director/basket/create',
null,
['class' => 'icon-plus']
)
),
Link::create(
$this->translate('Upload'),
'director/basket/upload',
null,
['class' => 'icon-upload']
),
]);
$this->addTitle($this->translate('Configuration Baskets'));
$this->content()->add(Html::tag('p', $this->translate(

View File

@ -0,0 +1,145 @@
<?php
namespace Icinga\Module\Director\Forms;
use Exception;
use Icinga\Exception\IcingaException;
use Icinga\Module\Director\Core\Json;
use Icinga\Module\Director\DirectorObject\Automation\Basket;
use Icinga\Module\Director\DirectorObject\Automation\BasketSnapshot;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Web\Notification;
class BasketUploadForm extends DirectorObjectForm
{
protected $listUrl = 'director/baskets';
protected $failed;
protected $upload;
protected $rawUpload;
/**
* @throws \Zend_Form_Exception
*/
public function setup()
{
$this->addElement('text', 'basket_name', [
'label' => $this->translate('Basket Name'),
'required' => true,
]);
$this->setAttrib('enctype', 'multipart/form-data');
$this->addElement('file', 'uploaded_file', [
'label' => $this->translate('Choose file'),
'destination' => $this->getTempDir(),
'valueDisabled' => true,
'isArray' => false,
'multiple' => false,
'ignore' => true,
]);
$this->setSubmitLabel($this->translate('Upload'));
}
protected function getTempDir()
{
return sys_get_temp_dir();
}
protected function getObjectClassname()
{
return '\\Icinga\\Module\\Director\\DirectorObject\\Automation\\Basket';
}
protected function setObjectSuccessUrl()
{
/** @var Basket $basket */
$basket = $this->object();
$this->setSuccessUrl(
'director/basket',
['name' => $basket->get('basket_name')]
);
}
/**
* @return bool
* @throws IcingaException
*/
protected function processUploadedSource()
{
if (! array_key_exists('uploaded_file', $_FILES)) {
throw new IcingaException('Got no file');
}
if (! isset($_FILES['uploaded_file']['tmp_name'])
|| ! is_uploaded_file($_FILES['uploaded_file']['tmp_name'])
) {
$this->addError('Got no uploaded file');
$this->failed = true;
return false;
}
$tmpFile = $_FILES['uploaded_file']['tmp_name'];
$originalFilename = $_FILES['uploaded_file']['name'];
$source = file_get_contents($tmpFile);
unlink($tmpFile);
try {
$json = Json::decode($source);
$this->rawUpload = $source;
$this->upload = $json;
} catch (Exception $e) {
$this->addError($originalFilename . ' failed: ' . $e->getMessage());
Notification::error($originalFilename . ' failed: ' . $e->getMessage());
$this->failed = true;
return false;
}
return true;
}
public function onRequest()
{
if ($this->hasBeenSent()) {
try {
$this->processUploadedSource();
} catch (Exception $e) {
$this->addError($e->getMessage());
return;
}
}
}
/**
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
*/
public function onSuccess()
{
/** @var Basket $basket */
$basket = $this->object();
foreach ($this->upload as $type => $content) {
$basket->addObjects($type, array_keys((array) $content));
}
if ($basket->isEmpty()) {
$this->addError($this->translate("It's not allowed to store an empty basket"));
return;
}
$basket->set('owner_type', 'user');
$basket->set('owner_value', $this->getAuth()->getUser()->getUsername());
$basket->store($this->db);
BasketSnapshot::forBasketFromJson(
$basket,
$this->rawUpload
)->store($this->db);
$this->setObjectSuccessUrl();
$this->beforeSuccessfulRedirect();
$this->redirectOnSuccess($this->translate('Basket has been uploaded'));
}
}

View File

@ -175,6 +175,21 @@ class BasketSnapshot extends DbObject
);
}
/**
* @param Basket $basket
* @param $string
* @return BasketSnapshot
*/
public static function forBasketFromJson(Basket $basket, $string)
{
$snapshot = static::create([
'basket_uuid' => $basket->get('uuid')
]);
$snapshot->objects = Json::decode($string);
return $snapshot;
}
public static function restoreJson($string, Db $connection, $replace = true)
{
$snapshot = new static();