host = substr($this->getNode()->getName(), 0, strpos($this->getNode()->getName(), ';'));
if ($this->isService()) {
$this->service = substr($this->getNode()->getName(), strpos($this->getNode()->getName(), ';') + 1);
}
$view = $this->getView();
$this->addHtml(
'
' . $view->escape(
sprintf($this->translate('Modify "%s"'), $this->getNode()->getAlias())
) . '
'
);
$monitoredNodeType = null;
if ($this->isService()) {
$monitoredNodeType = 'service';
} else {
$monitoredNodeType = 'host';
}
$type = $this->selectNodeType($monitoredNodeType);
switch ($type) {
case 'host':
$this->selectHost();
break;
case 'service':
$this->selectService();
break;
case 'process':
$this->selectProcess();
break;
case 'new-process':
$this->addNewProcess();
break;
case null:
$this->setSubmitLabel($this->translate('Next'));
return;
}
}
protected function isService()
{
if (strpos($this->getNode()->getName(), ';Hoststatus')) {
return false;
}
return true;
}
protected function addNewProcess()
{
$this->addElement('text', 'name', array(
'label' => $this->translate('ID'),
'required' => true,
'disabled' => true,
'description' => $this->translate(
'This is the unique identifier of this process'
),
));
$this->addElement('text', 'alias', array(
'label' => $this->translate('Display Name'),
'description' => $this->translate(
'Usually this name will be shown for this node. Equals ID'
. ' if not given'
),
));
$this->addElement('select', 'operator', array(
'label' => $this->translate('Operator'),
'required' => true,
'multiOptions' => array(
'&' => $this->translate('AND'),
'|' => $this->translate('OR'),
'!' => $this->translate('NOT'),
'%' => $this->translate('DEGRADED'),
'1' => $this->translate('MIN 1'),
'2' => $this->translate('MIN 2'),
'3' => $this->translate('MIN 3'),
'4' => $this->translate('MIN 4'),
'5' => $this->translate('MIN 5'),
'6' => $this->translate('MIN 6'),
'7' => $this->translate('MIN 7'),
'8' => $this->translate('MIN 8'),
'9' => $this->translate('MIN 9'),
)
));
$display = $this->getNode()->getDisplay() ?: 1;
$this->addElement('select', 'display', array(
'label' => $this->translate('Visualization'),
'required' => true,
'description' => $this->translate(
'Where to show this process'
),
'value' => $display,
'multiOptions' => array(
"$display" => $this->translate('Toplevel Process'),
'0' => $this->translate('Subprocess only'),
)
));
$this->addElement('text', 'infoUrl', array(
'label' => $this->translate('Info URL'),
'description' => $this->translate(
'URL pointing to more information about this node'
)
));
}
/**
* @return string|null
*/
protected function selectNodeType($monitoredNodeType = null)
{
if ($this->hasParentNode()) {
$this->addElement('hidden', 'node_type', [
'disabled' => true,
'decorators' => ['ViewHelper'],
'value' => $monitoredNodeType
]);
return $monitoredNodeType;
} elseif (! $this->hasProcesses()) {
$this->addElement('hidden', 'node_type', array(
'ignore' => true,
'decorators' => array('ViewHelper'),
'value' => 'new-process'
));
return 'new-process';
}
}
protected function selectHost()
{
$this->addElement('select', 'children', array(
'required' => true,
'value' => $this->getNode()->getName(),
'multiOptions' => $this->enumHostList(),
'label' => $this->translate('Host'),
'description' => $this->translate('The host for this business process node'),
'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]]
));
$this->addHostOverrideCheckbox();
$hostOverrideSent = $this->getSentValue('host_override');
if ($hostOverrideSent === '1'
|| ($hostOverrideSent === null && $this->getElement('host_override')->isChecked())
) {
$this->addHostOverrideElement();
}
}
protected function selectService()
{
$this->addHostElement();
if ($this->getSentValue('hosts') === null) {
$this->addServicesElement($this->host);
$this->addServiceOverrideCheckbox();
if ($this->getElement('service_override')->isChecked() || $this->getSentValue('service_override') === '1') {
$this->addServiceOverrideElement();
}
} elseif ($host = $this->getSentValue('hosts')) {
$this->addServicesElement($host);
$this->addServiceOverrideCheckbox();
if ($this->getSentValue('service_override') === '1') {
$this->addServiceOverrideElement();
}
} else {
$this->setSubmitLabel($this->translate('Next'));
}
}
protected function addHostElement()
{
$this->addElement('select', 'hosts', array(
'label' => $this->translate('Host'),
'required' => true,
'ignore' => true,
'class' => 'autosubmit',
'multiOptions' => $this->optionalEnum($this->enumHostForServiceList()),
));
$this->getElement('hosts')->setValue($this->host);
}
protected function addHostOverrideCheckbox()
{
$this->addElement('checkbox', 'host_override', [
'ignore' => true,
'class' => 'autosubmit',
'value' => ! empty($this->parent->getStateOverrides($this->node->getName())),
'label' => $this->translate('Override Host State'),
'description' => $this->translate('Enable host state overrides')
]);
}
protected function addHostOverrideElement()
{
$this->addElement('stateOverrides', 'stateOverrides', [
'required' => true,
'states' => $this->enumHostStateList(),
'value' => $this->parent->getStateOverrides($this->node->getName()),
'label' => $this->translate('State Overrides')
]);
}
protected function addServicesElement($host)
{
$this->addElement('select', 'children', array(
'required' => true,
'value' => $this->getNode()->getName(),
'multiOptions' => $this->enumServiceList($host),
'label' => $this->translate('Service'),
'description' => $this->translate('The service for this business process node'),
'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]]
));
}
protected function addServiceOverrideCheckbox()
{
$this->addElement('checkbox', 'service_override', [
'ignore' => true,
'class' => 'autosubmit',
'value' => ! empty($this->parent->getStateOverrides($this->node->getName())),
'label' => $this->translate('Override Service State'),
'description' => $this->translate('Enable service state overrides')
]);
}
protected function addServiceOverrideElement()
{
$this->addElement('stateOverrides', 'stateOverrides', [
'required' => true,
'states' => $this->enumServiceStateList(),
'value' => $this->parent->getStateOverrides($this->node->getName()),
'label' => $this->translate('State Overrides')
]);
}
protected function selectProcess()
{
$this->addElement('multiselect', 'children', array(
'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'
)
));
}
/**
* @param MonitoringBackend|IcingaDbConnection $backend
* @return $this
*/
public function setBackend($backend)
{
$this->backend = $backend;
return $this;
}
/**
* @param BpConfig $process
* @return $this
*/
public function setProcess(BpConfig $process)
{
$this->bp = $process;
$this->setBackend($process->getBackend());
return $this;
}
/**
* @param BpNode|null $node
* @return $this
*/
public function setParentNode(BpNode $node = null)
{
$this->parent = $node;
return $this;
}
/**
* @return bool
*/
public function hasParentNode()
{
return $this->parent !== null;
}
/**
* @param SessionNamespace $session
* @return $this
*/
public function setSession(SessionNamespace $session)
{
$this->session = $session;
return $this;
}
protected function hasProcesses()
{
return count($this->enumProcesses()) > 0;
}
protected function enumProcesses()
{
$list = array();
$parents = array();
if ($this->hasParentNode()) {
$this->collectAllParents($this->parent, $parents);
$parents[$this->parent->getName()] = $this->parent;
}
foreach ($this->bp->getNodes() as $node) {
if ($node instanceof BpNode && ! isset($parents[$node->getName()])) {
$list[$node->getName()] = $node->getName(); // display name?
}
}
if (! $this->bp->getMetadata()->isManuallyOrdered()) {
natcasesort($list);
}
return $list;
}
/**
* Collect the given node's parents recursively into the given array by their names
*
* @param BpNode $node
* @param BpNode[] $parents
*/
protected function collectAllParents(BpNode $node, array &$parents)
{
foreach ($node->getParents() as $parent) {
$parents[$parent->getName()] = $parent;
$this->collectAllParents($parent, $parents);
}
}
/**
* @param Node $node
* @return $this
*/
public function setNode(Node $node)
{
$this->node = $node;
return $this;
}
public function getNode()
{
return $this->node;
}
public function onSuccess()
{
$changes = ProcessChanges::construct($this->bp, $this->session);
$changes->deleteNode($this->node, $this->parent->getName());
switch ($this->getValue('node_type')) {
case 'host':
case 'service':
$stateOverrides = $this->getValue('stateOverrides') ?: [];
if (! empty($stateOverrides)) {
$stateOverrides = array_merge(
$this->parent->getStateOverrides(),
[$this->getValue('children') => $stateOverrides]
);
} else {
$stateOverrides = $this->parent->getStateOverrides();
unset($stateOverrides[$this->getValue('children')]);
}
$changes->modifyNode($this->parent, ['stateOverrides' => $stateOverrides]);
// Fallthrough
case 'process':
$changes->addChildrenToNode($this->getValue('children'), $this->parent);
break;
case 'new-process':
$properties = $this->getValues();
unset($properties['name']);
if ($this->hasParentNode()) {
$properties['parentName'] = $this->parent->getName();
}
$changes->createNode($this->getValue('name'), $properties);
break;
}
// Trigger session destruction to make sure it get's stored.
// TODO: figure out why this is necessary, might be an unclean shutdown on redirect
unset($changes);
parent::onSuccess();
}
public function isValid($data)
{
// Don't allow to override disabled elements. This is probably too harsh
// but also wouldn't be necessary if this would be a Icinga\Web\Form...
foreach ($this->getElements() as $element) {
/** @var \Zend_Form_Element $element */
if ($element->getAttrib('disabled')) {
$data[$element->getName()] = $element->getValue();
}
}
return parent::isValid($data);
}
}