getView(); if ($this->hasParentNode()) { $this->addHtml( '

' . $view->escape( sprintf($this->translate('Add a node to %s'), $this->parent->getAlias()) ) . '

' ); } else { $this->addHtml( '

' . $this->translate('Add a new root node') . '

' ); } $type = $this->selectNodeType(); switch ($type) { case 'host': $this->selectHost(); break; case 'service': $this->selectService(); break; case 'process': $this->selectProcess(); break; case 'new-process': $this->addNewProcess(); break; case 'hosts_from_filter': $this->selectHostsFromFilter(); break; case 'services_from_filter': $this->selectServicesFromFilter(); break; case null: $this->setSubmitLabel($this->translate('Next')); return; } } protected function addNewProcess() { $this->addElement('text', 'name', array( 'label' => $this->translate('ID'), 'required' => true, 'description' => $this->translate( 'This is the unique identifier of this process' ), 'validators' => [ ['Callback', true, [ 'callback' => function ($value) { if ($this->hasParentNode()) { return ! $this->parent->hasChild($value); } return ! $this->bp->hasRootNode($value); }, 'messages' => [ 'callbackValue' => $this->translate('%value% is already defined in 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 = 1; if ($this->bp->getMetadata()->isManuallyOrdered() && !$this->bp->isEmpty()) { $rootNodes = $this->bp->getRootNodes(); $display = end($rootNodes)->getDisplay() + 1; } $this->addElement('select', 'display', array( 'label' => $this->translate('Visualization'), 'required' => true, 'description' => $this->translate( 'Where to show this process' ), 'value' => $this->hasParentNode() ? '0' : "$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() { $types = array(); if ($this->hasParentNode()) { $types['host'] = $this->translate('Host'); $types['service'] = $this->translate('Service'); $types['hosts_from_filter'] = $this->translate('Hosts from filter'); $types['services_from_filter'] = $this->translate('Services from filter'); } elseif (! $this->hasProcesses()) { $this->addElement('hidden', 'node_type', array( 'ignore' => true, 'decorators' => array('ViewHelper'), 'value' => 'new-process' )); return 'new-process'; } if ($this->hasProcesses() || ($this->hasParentNode() && $this->hasMoreConfigs())) { $types['process'] = $this->translate('Existing Process'); } $types['new-process'] = $this->translate('New Process Node'); $this->addElement('select', 'node_type', array( 'label' => $this->translate('Node type'), 'required' => true, 'description' => $this->translate( 'The node type you want to add' ), 'ignore' => true, 'class' => 'autosubmit', 'multiOptions' => $this->optionalEnum($types) )); return $this->getSentValue('node_type'); } protected function selectHost() { $this->addElement('multiselect', 'children', [ 'label' => $this->translate('Hosts'), 'required' => true, 'size' => 8, 'style' => 'width: 25em', 'multiOptions' => $this->enumHostList(), 'description' => $this->translate( 'Hosts that should be part of this business process node' ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); $this->addHostOverrideCheckbox(); if ($this->getSentValue('host_override') === '1') { $this->addHostOverrideElement(); } } protected function selectService() { $this->addHostElement(); if ($host = $this->getSentValue('host')) { $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', 'host', array( 'label' => $this->translate('Host'), 'required' => true, 'ignore' => true, 'class' => 'autosubmit', 'multiOptions' => $this->optionalEnum($this->enumHostForServiceList()), )); } protected function addServicesElement($host) { $this->addElement('multiselect', 'children', [ 'label' => $this->translate('Services'), 'required' => true, 'size' => 8, 'style' => 'width: 25em', 'multiOptions' => $this->enumServiceList($host), 'description' => $this->translate( 'Services that should be part of this business process node' ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); } protected function addFilteredHostsElement($filter) { $this->addElement('submit', 'refresh', [ 'label' => $this->translate('Refresh'), 'class' => 'refresh-filter' ]); $this->addElement('multiselect', 'children', [ 'label' => $this->translate('Hosts'), 'required' => true, 'size' => 8, 'style' => 'width: 25em', 'multiOptions' => $this->enumHostListByFilter($filter), 'description' => $this->translate( 'Hosts that should be part of this business process node' ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); } protected function addFilteredServicesElement($filter) { $this->addElement('submit', 'refresh', [ 'label' => $this->translate('Refresh'), 'class' => 'refresh-filter' ]); $this->addElement('multiselect', 'children', [ 'label' => $this->translate('Services'), 'required' => true, 'size' => 8, 'style' => 'width: 25em', 'multiOptions' => $this->enumServiceListByFilter($filter), 'description' => $this->translate( 'Services that should be part of this business process node' ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); } protected function addFilterElement() { $this->addElement('text', 'filter', array( 'label' => $this->translate('Filter'), 'required' => true, 'ignore' => true )); } 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 addHostOverrideCheckbox() { $this->addElement('checkbox', 'host_override', [ 'ignore' => true, 'class' => 'autosubmit', 'label' => $this->translate('Override Host State'), 'description' => $this->translate('Enable host state overrides') ]); } protected function addHostOverrideElement() { $this->addElement('stateOverrides', 'stateOverrides', [ 'required' => true, 'label' => $this->translate('State Overrides'), 'states' => $this->enumHostStateList() ]); } protected function addServiceOverrideCheckbox() { $this->addElement('checkbox', 'service_override', [ 'ignore' => true, 'class' => 'autosubmit', 'label' => $this->translate('Override Service State'), 'description' => $this->translate('Enable service state overrides') ]); } protected function addServiceOverrideElement() { $this->addElement('stateOverrides', 'stateOverrides', [ 'required' => true, 'label' => $this->translate('State Overrides'), 'states' => $this->enumServiceStateList() ]); } protected function selectHostsFromFilter() { $this->addFilterElement(); if ($filter = $this->getSentValue('filter')) { $this->addFilteredHostsElement($filter); } else { $this->setSubmitLabel($this->translate('Next')); } } protected function selectServicesFromFilter() { $this->addFilterElement(); if ($filter = $this->getSentValue('filter')) { $this->addFilteredServicesElement($filter); } else { $this->setSubmitLabel($this->translate('Next')); } } protected function selectProcess() { if ($this->hasParentNode()) { $this->addFileElement(); } if (($file = $this->getSentValue('file')) || !$this->hasParentNode()) { $this->addElement('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' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); } else { $this->setSubmitLabel($this->translate('Next')); } } /** * @param MonitoringBackend|IcingaDbConnection $backend * @return $this */ public function setBackend($backend) { $this->backend = $backend; return $this; } /** * @param Storage $storage * @return $this */ public function setStorage(Storage $storage) { $this->storage = $storage; 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; } /** * @param string $file * @return array */ protected function enumProcesses($file = null) { $list = array(); $parents = array(); $differentFile = $file !== null && $file !== $this->bp->getName(); if (! $differentFile && $this->hasParentNode()) { $this->collectAllParents($this->parent, $parents); $parents[$this->parent->getName()] = $this->parent; } $bp = $this->bp; if ($differentFile) { $bp = $this->storage->loadProcess($file); } foreach ($bp->getNodes() as $node) { if (! $node instanceof ImportedNode && $node instanceof BpNode && ! isset($parents[$node->getName()])) { $name = $node->getName(); if ($differentFile) { $name = '@' . $file . ':' . $name; } $list[$name] = $node->getName(); // display name? } } if (! $this->bp->getMetadata()->isManuallyOrdered()) { natcasesort($list); } 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 * * @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); } } public function onSuccess() { $changes = ProcessChanges::construct($this->bp, $this->session); switch ($this->getValue('node_type')) { case 'host': case 'service': $stateOverrides = $this->getValue('stateOverrides'); if (! empty($stateOverrides)) { $childOverrides = []; foreach ($this->getValue('children') as $service) { $childOverrides[$service] = $stateOverrides; } $changes->modifyNode($this->parent, [ 'stateOverrides' => array_merge($this->parent->getStateOverrides(), $childOverrides) ]); } // Fallthrough case 'process': case 'hosts_from_filter': case 'services_from_filter': 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(); 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(); } }