Allow to import processes from different configurations

This commit is contained in:
Johannes Meyer 2019-01-16 10:25:11 +01:00
parent a707ee3eb7
commit 327cb7c28c
5 changed files with 155 additions and 38 deletions

View file

@ -216,6 +216,7 @@ class ProcessController extends Controller
if ($action === 'add' && $canEdit) {
$form = $this->loadForm('AddNode')
->setSuccessUrl(Url::fromRequest()->without('action'))
->setStorage($this->storage())
->setProcess($bp)
->setParentNode($node)
->setSession($this->session())

View file

@ -6,6 +6,7 @@ use Icinga\Module\Businessprocess\BpNode;
use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
use Icinga\Module\Businessprocess\Web\Form\Element\Multiselect;
use Icinga\Module\Businessprocess\Storage\Storage;
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
use Icinga\Web\Session\SessionNamespace;
@ -15,6 +16,9 @@ class AddNodeForm extends QuickForm
/** @var MonitoringBackend */
protected $backend;
/** @var Storage */
protected $storage;
/** @var BpConfig */
protected $bp;
@ -140,7 +144,7 @@ class AddNodeForm extends QuickForm
return 'new-process';
}
if ($this->hasProcesses()) {
if ($this->hasProcesses() || ($this->hasParentNode() && $this->hasMoreConfigs())) {
$types['process'] = $this->translate('Existing Process');
}
@ -239,33 +243,56 @@ class AddNodeForm extends QuickForm
]));
}
protected function addFileElement()
{
$this->addElement('select', 'file', [
'label' => $this->translate('File'),
'required' => true,
'ignore' => true,
'value' => $this->bp->getName(),
'class' => 'autosubmit',
'multiOptions' => $this->optionalEnum($this->enumConfigs()),
'description' => $this->translate(
'Choose a different configuration file to import its processes'
)
]);
}
protected function selectProcess()
{
$this->addElement(new Multiselect('children', [
'label' => $this->translate('Process nodes'),
'required' => true,
'size' => 8,
'style' => 'width: 25em',
'multiOptions' => $this->enumProcesses(),
'description' => $this->translate(
'Other processes that should be part of this business process node'
),
'validators' => [
['Callback', true, [
'callback' => function ($value) {
if ($this->hasParentNode() && $this->parent->hasChild($value)) {
$el = $this->getElement('children');
$el->addError(sprintf(
$this->translate('%s is already defined in this process'),
$el->getMultiOptions()[$value]
));
}
if ($this->hasParentNode()) {
$this->addFileElement();
}
return true;
}
]]
]
]));
if (($file = $this->getSentValue('file')) || !$this->hasParentNode()) {
$this->addElement(new Multiselect('children', [
'label' => $this->translate('Process nodes'),
'required' => true,
'size' => 8,
'style' => 'width: 25em',
'multiOptions' => $this->enumProcesses($file),
'description' => $this->translate(
'Other processes that should be part of this business process node'
),
'validators' => [
['Callback', true, [
'callback' => function ($value) {
if ($this->hasParentNode() && $this->parent->hasChild($value)) {
$el = $this->getElement('children');
$el->addError(sprintf(
$this->translate('%s is already defined in this process'),
$el->getMultiOptions()[$value]
));
}
return true;
}
]]
]
]));
} else {
$this->setSubmitLabel($this->translate('Next'));
}
}
/**
@ -278,6 +305,16 @@ class AddNodeForm extends QuickForm
return $this;
}
/**
* @param Storage $storage
* @return $this
*/
public function setStorage(Storage $storage)
{
$this->storage = $storage;
return $this;
}
/**
* @param BpConfig $process
* @return $this
@ -368,20 +405,36 @@ class AddNodeForm extends QuickForm
return count($this->enumProcesses()) > 0;
}
protected function enumProcesses()
/**
* @param string $file
* @return array
*/
protected function enumProcesses($file = null)
{
$list = array();
$parents = array();
if ($this->hasParentNode()) {
$differentFile = $file !== null && $file !== $this->bp->getName();
if (! $differentFile && $this->hasParentNode()) {
$this->collectAllParents($this->parent, $parents);
$parents[$this->parent->getName()] = $this->parent;
}
foreach ($this->bp->getNodes() as $node) {
$bp = $this->bp;
if ($differentFile) {
$bp = $this->storage->loadProcess($file);
}
foreach ($bp->getNodes() as $node) {
if ($node instanceof BpNode && ! isset($parents[$node->getName()])) {
$list[(string) $node] = (string) $node; // display name?
$name = $node->getName();
if ($differentFile) {
$name = '@' . $file . ':' . $name;
}
$list[$name] = (string) $node; // display name?
}
}
@ -389,6 +442,17 @@ class AddNodeForm extends QuickForm
return $list;
}
protected function hasMoreConfigs()
{
$configs = $this->enumConfigs();
return !empty($configs);
}
protected function enumConfigs()
{
return $this->storage->listProcesses();
}
/**
* Collect the given node's parents recursively into the given array by their names
*
@ -443,7 +507,14 @@ class AddNodeForm extends QuickForm
case 'host':
case 'service':
case 'process':
$changes->addChildrenToNode($this->getValue('children'), $this->parent);
if ($this->hasParentNode()) {
$changes->addChildrenToNode($this->getValue('children'), $this->parent);
} else {
foreach ($this->getValue('children') as $nodeName) {
$changes->copyNode($nodeName);
}
}
break;
case 'new-process':
$properties = $this->getValues();

View file

@ -3,7 +3,6 @@
namespace Icinga\Module\Businessprocess\Modification;
use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\BpNode;
class NodeAddChildrenAction extends NodeAction
{
@ -30,13 +29,6 @@ class NodeAddChildrenAction extends NodeAction
*/
public function applyTo(BpConfig $config)
{
/** @var BpNode $node */
if (! $this->hasNode()) {
// TODO: We end up here when defining "top nodes", but that would probably
// be a different action
return $this;
}
$node = $config->getBpNode($this->getNodeName());
foreach ($this->children as $name) {
@ -49,6 +41,9 @@ class NodeAddChildrenAction extends NodeAction
} else {
$config->createService($host, $service);
}
} elseif ($name[0] === '@' && strpos($name, ':') !== false) {
list($configName, $nodeName) = preg_split('~:\s*~', substr($name, 1), 2);
$config->createImportedNode($configName, $nodeName);
}
}
$node->addChild($config->getNode($name));

View file

@ -0,0 +1,39 @@
<?php
namespace Icinga\Module\Businessprocess\Modification;
use Icinga\Module\Businessprocess\BpConfig;
class NodeCopyAction extends NodeAction
{
/**
* @param BpConfig $config
* @return bool
*/
public function appliesTo(BpConfig $config)
{
$name = $this->getNodeName();
if (! $config->hasBpNode($name)) {
$this->error('Process "%s" not found', $name);
}
if ($config->hasRootNode($name)) {
$this->error('A toplevel node with name "%s" already exists', $name);
}
return true;
}
/**
* @param BpConfig $config
*/
public function applyTo(BpConfig $config)
{
$name = $this->getNodeName();
$rootNodes = $config->getRootNodes();
$config->addRootNode($name)
->getBpNode($name)
->setDisplay(end($rootNodes)->getDisplay() + 1);
}
}

View file

@ -94,6 +94,17 @@ class ProcessChanges
return $this->push($action);
}
/**
* @param $nodeName
* @param Node|null $parent
* @return $this
*/
public function copyNode($nodeName)
{
$action = new NodeCopyAction($nodeName);
return $this->push($action, true);
}
/**
* @param Node $node
* @param string $parentName