Merge branch 'feature/send-commands-4441'

resolves #4441
This commit is contained in:
Jannis Moßhammer 2013-08-06 09:58:42 +02:00
commit cc77a55435
31 changed files with 1444 additions and 328 deletions

View File

@ -32,33 +32,42 @@ use \Icinga\Protocol\Commandpipe\Exception\InvalidCommandException;
use \Icinga\Protocol\Commandpipe\Comment; use \Icinga\Protocol\Commandpipe\Comment;
/** /**
* Class Acknowledgement * Container for a host/service Acknowledgement
* @package Icinga\Protocol\Commandpipe
*/ */
class Acknowledgement implements IComment class Acknowledgement implements IComment
{ {
/** /**
* The expire time of this acknowledgement or -1 if no expire time is used
*
* @var int * @var int
*/ */
public $expireTime = -1; private $expireTime = -1;
/** /**
* Whether to set the notify flag of the acknowledgment
*
* @var bool * @var bool
*/ */
public $notify = false; private $notify = false;
/** /**
* @var Comment|null * The comment text of this acknowledgment
*
* @var Comment
*/ */
public $comment = null; private $comment;
/** /**
* true if this is a sticky acknowledgment
*
* @var bool * @var bool
*/ */
public $sticky; public $sticky;
/** /**
* @param int $time * Set the expire time of this acknowledgment to $time
*
* @param int $time The new expire time as a UNIX timestamp
*/ */
public function setExpireTime($time) public function setExpireTime($time)
{ {
@ -66,7 +75,9 @@ class Acknowledgement implements IComment
} }
/** /**
* @param boolean $bool * Set the notify flag of this object
*
* @param boolean $bool True if notify should be set, otherwise false
*/ */
public function setNotify($bool) public function setNotify($bool)
{ {
@ -74,10 +85,12 @@ class Acknowledgement implements IComment
} }
/** /**
* @param Comment $comment * Create a new acknowledgment container
* @param bool $notify *
* @param $expire * @param Comment $comment The comment to use for the acknowledgement
* @param bool $sticky * @param bool $notify Whether to set the notify flag
* @param int $expire The expire time or -1 of not expiring
* @param bool $sticky Whether to set the sticky flag
*/ */
public function __construct(Comment $comment, $notify = false, $expire = -1, $sticky = false) public function __construct(Comment $comment, $notify = false, $expire = -1, $sticky = false)
{ {
@ -88,9 +101,11 @@ class Acknowledgement implements IComment
} }
/** /**
* @param $type * Return the ACKNOWLEDGE_?_PROBLEM string to be used for submitting an external icinga command
* @return string *
* @throws Exception\InvalidCommandException * @param string $type Either CommandPipe::TYPE_HOST or CommandPipe::TYPE_SERVICE
* @return string The command string to be submitted to the command pipe
* @throws InvalidCommandException
*/ */
public function getFormatString($type) public function getFormatString($type)
{ {

View File

@ -30,141 +30,121 @@ namespace Icinga\Protocol\Commandpipe;
use Icinga\Application\Logger as IcingaLogger; use Icinga\Application\Logger as IcingaLogger;
use Icinga\Protocol\Commandpipe\Transport\Transport;
use Icinga\Protocol\Commandpipe\Transport\LocalPipe;
use Icinga\Protocol\Commandpipe\Transport\SecureShell;
/** /**
* Class CommandPipe * Class to the access icinga CommandPipe via a @see Icinga\Protocol\Commandpipe\Transport.php
* @package Icinga\Protocol\Commandpipe *
* Will be configured using the instances.ini
*/ */
class CommandPipe class CommandPipe
{ {
/** /**
* @var mixed * The name of this class as defined in the instances.ini
*/ *
private $path;
/**
* @var mixed
*/
private $name;
/**
* @var bool|mixed
*/
private $user = false;
/**
* @var bool|mixed
*/
private $host = false;
/**
* @var int|mixed
*/
private $port = 22;
/**
* @var string * @var string
*/ */
public $fopen_mode = "w"; private $name = "";
/** /**
* The underlying @see Icinga\Protocol\Commandpipe\Transport.php class handling communication with icinga
* *
* @var Icinga\Protocol\Commandpipe\Transport
*/
private $transport = null;
/**
* Constant identifying a monitoring object as host
*/ */
const TYPE_HOST = "HOST"; const TYPE_HOST = "HOST";
/** /**
* * Constant identifying a monitoring object as service
*/ */
const TYPE_SERVICE = "SVC"; const TYPE_SERVICE = "SVC";
/** /**
* * Constant identifying a monitoring object as hostgroup
*/ */
const TYPE_HOSTGROUP = "HOSTGROUP"; const TYPE_HOSTGROUP = "HOSTGROUP";
/** /**
* * Constant identifying a monitoring object as servicegroups
*/ */
const TYPE_SERVICEGROUP = "SERVICEGROUP"; const TYPE_SERVICEGROUP = "SERVICEGROUP";
/** /**
* Notification option (use logical OR for combination)
*
* Broadcast (send notification to all normal and all escalated contacts for the service)
*/
const NOTIFY_BROADCAST = 1;
/**
* Notification option (use logical OR for combination)
*
* notification is sent out regardless of current time, whether or not notifications are enabled, etc.
*/
const NOTIFY_FORCED = 2;
/**
* Notification option (use logical OR for combination)
*
* Increment current notification # for the service(this is not done by default for custom notifications)
*/
const NOTIFY_INCREMENT = 4;
/**
* Create a new CommandPipe class which accesses the icinga.cmd pipe as defined in $config
*
* @param \Zend_Config $config * @param \Zend_Config $config
*/ */
public function __construct(\Zend_Config $config) public function __construct(\Zend_Config $config)
{ {
$this->path = $config->path; $this->getTransportForConfiguration($config);
$this->name = $config->name; $this->name = $config->name;
}
/**
* Setup the @see Icinga\Protocol\Commandpipe\Transport.php class that will be used for accessing the command pipe
*
* Currently this method uses SecureShell when a host is given, otherwise it assumes the pipe is accessible
* via the machines filesystem
*
* @param \Zend_Config $config The configuration as defined in the instances.ini
*/
private function getTransportForConfiguration(\Zend_Config $config)
{
if (isset($config->host)) { if (isset($config->host)) {
$this->host = $config->host; $this->transport = new SecureShell();
} $this->transport->setEndpoint($config);
if (isset($config->port)) { } else {
$this->port = $config->port; $this->transport = new LocalPipe();
} $this->transport->setEndpoint($config);
if (isset($config->user)) {
$this->user = $config->user;
} }
} }
/** /**
* @param $command * Send the command string $command to the icinga pipe
* @throws \RuntimeException *
* This method just delegates the send command to the underlying transport
*
* @param String $command The command string to send, without the timestamp
*/ */
public function send($command) public function send($command)
{ {
if (!$this->host) { $this->transport->send($command);
IcingaLogger::debug(
"Attempting to send external icinga command $command to local command file {$this->path}"
);
$file = @fopen($this->path, $this->fopen_mode);
if (!$file) {
throw new \RuntimeException("Could not open icinga pipe at $file : " . print_r(error_get_last(), true));
}
fwrite($file, "[" . time() . "] " . $command . PHP_EOL);
IcingaLogger::debug('Writing [' . time() . '] ' . $command . PHP_EOL);
fclose($file);
} else {
// send over ssh
$retCode = 0;
$output = array();
IcingaLogger::debug(
'Icinga instance is on different host, attempting to send command %s via ssh to %s:%s/%s',
$command,
$this->host,
$this->port,
$this->path
);
$hostConnector = $this->user ? $this->user . "@" . $this->host : $this->host;
exec(
"ssh $hostConnector -p{$this->port} \"echo '[" . time() . "] "
. escapeshellcmd(
$command
)
. "' > {$this->path}\"",
$output,
$retCode
);
IcingaLogger::debug(
"$:ssh $hostConnector -p{$this->port} \"echo '[" . time() . "] " . escapeshellcmd(
$command
) . "' > {$this->path}\""
);
IcingaLogger::debug("Code code %s: %s ", $retCode, $output);
if ($retCode != 0) {
throw new \RuntimeException(
'Could not send command to remote icinga host: '
. implode(
"\n",
$output
)
. " (returncode $retCode)"
);
}
}
} }
/** /**
* @param $objects * Acknowledge a set of monitoring objects
* @param IComment $acknowledgementOrComment *
* $objects can be a mixed array of host and service objects
*
* @param array $objects An array of host and service objects
* @param IComment $acknowledgementOrComment An acknowledgement or comment object to use as the comment
*/ */
public function acknowledge($objects, IComment $acknowledgementOrComment) public function acknowledge($objects, IComment $acknowledgementOrComment)
{ {
@ -184,7 +164,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Remove the acknowledgements of the provided objects
*
* @param array $objects An array of mixed service and host objects whose acknowledgments will be removed
*/ */
public function removeAcknowledge($objects) public function removeAcknowledge($objects)
{ {
@ -198,15 +180,23 @@ class CommandPipe
} }
/** /**
* @param $objects * Submit passive check result for all provided objects
* @param $state *
* @param $output * @param array $objects An array of hosts and services to submit the passive check result to
* @param int $state The state to set for the monitoring objects
* @param string $output The output string to set as the check result
* @param string $perfdata The optional perfdata to submit as the check result
*/ */
public function submitCheckResult($objects, $state, $output) public function submitCheckResult($objects, $state, $output, $perfdata = "")
{ {
if ($perfdata) {
$output = $output."|".$perfdata;
}
foreach ($objects as $object) { foreach ($objects as $object) {
if (isset($object->service_description)) { if (isset($object->service_description)) {
$this->send("PROCESS_SVC_CHECK_RESULT;$object->host_name;$object->service_description;$state;$output"); $this->send(
"PROCESS_SERVICE_CHECK_RESULT;$object->host_name;$object->service_description;$state;$output"
);
} else { } else {
$this->send("PROCESS_HOST_CHECK_RESULT;$object->host_name;$state;$output"); $this->send("PROCESS_HOST_CHECK_RESULT;$object->host_name;$state;$output");
} }
@ -214,9 +204,11 @@ class CommandPipe
} }
/** /**
* @param $objects * Reschedule a forced check for all provided objects
* @param bool $time *
* @param bool $withChilds * @param array $objects An array of hosts and services to reschedule
* @param int|bool $time The time to submit, if empty time() will be used
* @param bool $withChilds Whether only childs should be rescheduled
*/ */
public function scheduleForcedCheck($objects, $time = false, $withChilds = false) public function scheduleForcedCheck($objects, $time = false, $withChilds = false)
{ {
@ -234,9 +226,11 @@ class CommandPipe
} }
/** /**
* @param $objects * Reschedule a check for all provided objects
* @param bool $time *
* @param bool $withChilds * @param array $objects An array of hosts and services to reschedule
* @param int|bool $time The time to submit, if empty time() will be used
* @param bool $withChilds Whether only childs should be rescheduled
*/ */
public function scheduleCheck($objects, $time = false, $withChilds = false) public function scheduleCheck($objects, $time = false, $withChilds = false)
{ {
@ -254,8 +248,10 @@ class CommandPipe
} }
/** /**
* @param array $objects * Add a comment to all submitted objects
* @param Comment $comment *
* @param array $objects An array of hosts and services to add a comment for
* @param Comment $comment The comment object to add
*/ */
public function addComment(array $objects, Comment $comment) public function addComment(array $objects, Comment $comment)
{ {
@ -272,7 +268,10 @@ class CommandPipe
} }
/** /**
* @param $objectsOrComments * Removes the submitted comments
*
* @param array $objectsOrComments An array of hosts and services (to remove all their comments)
* or single comment objects to remove
*/ */
public function removeComment($objectsOrComments) public function removeComment($objectsOrComments)
{ {
@ -300,6 +299,7 @@ class CommandPipe
} }
/** /**
* Globally enable notifications for this instance
* *
*/ */
public function enableGlobalNotifications() public function enableGlobalNotifications()
@ -308,6 +308,7 @@ class CommandPipe
} }
/** /**
* Globally disable notifications for this instance
* *
*/ */
public function disableGlobalNotifications() public function disableGlobalNotifications()
@ -316,8 +317,10 @@ class CommandPipe
} }
/** /**
* @param $object * Return the object type of the provided object (TYPE_SERVICE or TYPE_HOST)
* @return string *
* @param $object The object to identify
* @return string TYPE_SERVICE or TYPE_HOST
*/ */
private function getObjectType($object) private function getObjectType($object)
{ {
@ -329,8 +332,10 @@ class CommandPipe
} }
/** /**
* @param $objects * Schedule a downtime for all provided objects
* @param Downtime $downtime *
* @param array $objects An array of monitoring objects to schedule the downtime for
* @param Downtime $downtime The downtime object to schedule
*/ */
public function scheduleDowntime($objects, Downtime $downtime) public function scheduleDowntime($objects, Downtime $downtime)
{ {
@ -347,8 +352,10 @@ class CommandPipe
} }
/** /**
* @param $objects * Remove downtimes for objects
* @param int $starttime *
* @param array $objects An array containing hosts, service or downtime objects
* @param int $starttime An optional starttime to use for the DEL_DOWNTIME_BY_HOST_NAME command
*/ */
public function removeDowntime($objects, $starttime = 0) public function removeDowntime($objects, $starttime = 0)
{ {
@ -370,6 +377,7 @@ class CommandPipe
} }
/** /**
* Restart the icinga instance
* *
*/ */
public function restartIcinga() public function restartIcinga()
@ -378,8 +386,10 @@ class CommandPipe
} }
/** /**
* @param $objects * Modify monitoring flags for the provided objects
* @param PropertyModifier $flags *
* @param array $objects An arry of service and/or host objects to modify
* @param PropertyModifier $flags The Monitoring attributes to modify
*/ */
public function setMonitoringProperties($objects, PropertyModifier $flags) public function setMonitoringProperties($objects, PropertyModifier $flags)
{ {
@ -396,7 +406,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable active checks for all provided objects
*
* @param array $objects An array containing services and hosts to enable active checks for
*/ */
public function enableActiveChecks($objects) public function enableActiveChecks($objects)
{ {
@ -411,11 +423,13 @@ class CommandPipe
} }
/** /**
* @param $objects * Disable active checks for all provided objects
*
* @param array $objects An array containing services and hosts to disable active checks
*/ */
public function disableActiveChecks($objects) public function disableActiveChecks($objects)
{ {
$this->modifyMonitoringProperties( $this->setMonitoringProperties(
$objects, $objects,
new PropertyModifier( new PropertyModifier(
array( array(
@ -426,7 +440,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable passive checks for all provided objects
*
* @param array $objects An array containing services and hosts to enable passive checks for
*/ */
public function enablePassiveChecks($objects) public function enablePassiveChecks($objects)
{ {
@ -441,11 +457,13 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable passive checks for all provided objects
*
* @param array $objects An array containing services and hosts to enable passive checks for
*/ */
public function disablePassiveChecks($objects) public function disablePassiveChecks($objects)
{ {
$this->modifyMonitoringProperties( $this->setMonitoringProperties(
$objects, $objects,
new PropertyModifier( new PropertyModifier(
array( array(
@ -456,7 +474,10 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable flap detection for all provided objects
*
* @param array $objects An array containing services and hosts to enable flap detection
*
*/ */
public function enableFlappingDetection($objects) public function enableFlappingDetection($objects)
{ {
@ -471,7 +492,10 @@ class CommandPipe
} }
/** /**
* @param $objects * Disable flap detection for all provided objects
*
* @param array $objects An array containing services and hosts to disable flap detection
*
*/ */
public function disableFlappingDetection($objects) public function disableFlappingDetection($objects)
{ {
@ -486,7 +510,10 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable notifications for all provided objects
*
* @param array $objects An array containing services and hosts to enable notification
*
*/ */
public function enableNotifications($objects) public function enableNotifications($objects)
{ {
@ -501,7 +528,10 @@ class CommandPipe
} }
/** /**
* @param $objects * Disable flap detection for all provided objects
*
* @param array $objects An array containing services and hosts to disable notifications
*
*/ */
public function disableNotifications($objects) public function disableNotifications($objects)
{ {
@ -516,7 +546,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable freshness checks for all provided objects
*
* @param array $objects An array of hosts and/or services
*/ */
public function enableFreshnessChecks($objects) public function enableFreshnessChecks($objects)
{ {
@ -531,7 +563,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Disable freshness checks for all provided objects
*
* @param array $objects An array of hosts and/or services
*/ */
public function disableFreshnessChecks($objects) public function disableFreshnessChecks($objects)
{ {
@ -546,7 +580,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable event handler for all provided objects
*
* @param array $objects An array of hosts and/or services
*/ */
public function enableEventHandler($objects) public function enableEventHandler($objects)
{ {
@ -561,7 +597,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Disable event handler for all provided objects
*
* @param array $objects An array of hosts and/or services
*/ */
public function disableEventHandler($objects) public function disableEventHandler($objects)
{ {
@ -576,7 +614,9 @@ class CommandPipe
} }
/** /**
* @param $objects * Enable performance data parsing for all provided objects
*
* @param array $objects An array of hosts and/or services
*/ */
public function enablePerfdata($objects) public function enablePerfdata($objects)
{ {
@ -590,6 +630,11 @@ class CommandPipe
); );
} }
/**
* Disable performance data parsing for all provided objects
*
* @param array $objects An array of hosts and/or services
*/
public function disablePerfdata($objects) public function disablePerfdata($objects)
{ {
$this->setMonitoringProperties( $this->setMonitoringProperties(
@ -601,4 +646,202 @@ class CommandPipe
) )
); );
} }
/**
* Start obsessing over provided services/hosts
*
* @param array $objects An array of hosts and/or services
*/
public function startObsessing($objects)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
$msg = "START_OBSESSING_OVER_". (($type == self::TYPE_SERVICE) ? 'SVC' : 'HOST');
$msg .= ';'.$object->host_name;
if ($type == self::TYPE_SERVICE) {
$msg .= ';'.$object->service_description;
}
$this->send($msg);
}
}
/**
* Stop obsessing over provided services/hosts
*
* @param array $objects An array of hosts and/or services
*/
public function stopObsessing($objects)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
$msg = "STOP_OBSESSING_OVER_". (($type == self::TYPE_SERVICE) ? 'SVC' : 'HOST');
$msg .= ';'.$object->host_name;
if ($type == self::TYPE_SERVICE) {
$msg .= ';'.$object->service_description;
}
$this->send($msg);
}
}
/**
* Start obsessing over provided services/hosts
*
* @param array $objects An array of hosts and/or services
*/
public function startObsessing($objects)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
$msg = "START_OBSESSING_OVER_". (($type == self::TYPE_SERVICE) ? 'SVC' : 'HOST');
$msg .= ';'.$object->host_name;
if ($type == self::TYPE_SERVICE) {
$msg .= ';'.$object->service_description;
}
$this->send($msg);
}
}
/**
* Stop obsessing over provided services/hosts
*
* @param array $objects An array of hosts and/or services
*/
public function stopObsessing($objects)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
$msg = "STOP_OBSESSING_OVER_". (($type == self::TYPE_SERVICE) ? 'SVC' : 'HOST');
$msg .= ';'.$object->host_name;
if ($type == self::TYPE_SERVICE) {
$msg .= ';'.$object->service_description;
}
$this->send($msg);
}
}
/**
* Send a custom host or service notification
*
* @param $objects monitoring objects to send this notification to
* @param Comment $comment comment to use in the notification
* @param int [$...] Optional list of Notification flags which will be used as the option parameter
*/
public function sendCustomNotification($objects, Comment $comment, $optionsVarList = 0/*, ...*/)
{
$args = func_get_args();
// logical OR for all notification options
for ($i = 3; $i < count($args); $i++) {
$optionsVarList |= $args[$i];
}
foreach ($objects as $object) {
$type = $this->getObjectType($object);
$msg = 'SEND_CUSTOM_'.(($type == self::TYPE_SERVICE) ? 'SVC' : 'HOST' ).'_NOTIFICATION';
$msg .= ';'.$object->host_name;
if ($type == self::TYPE_SERVICE) {
$msg .= ';'.$object->service_description;
}
$msg .= ';'.$optionsVarList;
$msg .= ';'.$comment->author;
$msg .= ';'.$comment->comment;
$this->send($msg);
}
}
/**
* Disable notifications for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function disableNotificationsForServices($objects)
{
foreach ($objects as $host) {
$msg = 'DISABLE_HOST_SVC_NOTIFICATIONS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Enable notifications for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function enableNotificationsForServices($objects)
{
foreach ($objects as $host) {
$msg = 'ENABLE_HOST_SVC_NOTIFICATIONS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Disable active checks for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function disableActiveChecksWithChildren($objects)
{
foreach ($objects as $host) {
$msg = 'DISABLE_HOST_SVC_CHECKS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Enable active checks for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function enableActiveChecksWithChildren($objects)
{
foreach ($objects as $host) {
$msg = 'ENABLE_HOST_SVC_CHECKS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Reset modified attributes for all provided objects
*
* @param array $objects An array of hosts and services
*/
public function resetAttributes($objects)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
if ($type === self::TYPE_SERVICE) {
$this->send('CHANGE_SVC_MODATTR;'.$object->host_name.';'.$object->service_description.';0');
} else {
$this->send('CHANGE_HOST_MODATTR;'.$object->host_name.';0');
}
}
}
/**
* Delay notifications for all provided hosts and services for $time seconds
*
* @param array $objects An array of hosts and services
* @param int $time The number of seconds to delay notifications for
*/
public function delayNotification($objects, $time)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
if ($type === self::TYPE_SERVICE) {
$this->send('DELAY_SVC_NOTIFICATION;'.$object->host_name.';'.$object->service_description.';'.$time);
} else {
$this->send('DELAY_HOST_NOTIFICATION;'.$object->host_name.';'.$time);
}
}
}
/**
* Return the transport handler that handles actual sending of commands
*
* @return Transport
*/
public function getTransport()
{
return $this->transport;
}
} }

View File

@ -29,30 +29,38 @@
namespace Icinga\Protocol\Commandpipe; namespace Icinga\Protocol\Commandpipe;
/** /**
* Class Comment * Container for comment information that can be send to icinga's external command pipe
* @package Icinga\Protocol\Commandpipe *
*/ */
class Comment implements IComment class Comment implements IComment
{ {
/** /**
* Whether the persistent flag should be submitted with this command
*
* @var bool * @var bool
*/ */
public $persistent = false; public $persistent = false;
/** /**
* The author of this comment
*
* @var string * @var string
*/ */
public $author = ""; public $author = "";
/** /**
* The comment text to use
*
* @var string * @var string
*/ */
public $comment = ""; public $comment = "";
/** /**
* @param $author * Create a new comment object
* @param $comment *
* @param bool $persistent * @param string $author The author name to use for this object
* @param string $comment The comment text to use
* @param bool $persistent Whether this comment should persist icinga restarts
*/ */
public function __construct($author, $comment, $persistent = false) public function __construct($author, $comment, $persistent = false)
{ {
@ -62,9 +70,13 @@ class Comment implements IComment
} }
/** /**
* @param $type * Return this comment as an ADD_?_COMMENT external command string that can directly be send to the command pipe
* @return string *
* @throws InvalidCommandException * @param string $type either CommandPipe::TYPE_HOST or CommandPipe::TYPE_SERVICE
*
* @return string The ADD_HOST_COMMENT or ADD_SVC_COMMENT command, without the timestamp
*
* @throws InvalidCommandException When $type is unknown
*/ */
public function getFormatString($type) public function getFormatString($type)
{ {

View File

@ -29,63 +29,135 @@
namespace Icinga\Protocol\Commandpipe; namespace Icinga\Protocol\Commandpipe;
/** /**
* Class Downtime * Container class containing downtime information
* @package Icinga\Protocol\Commandpipe *
*/ */
class Downtime class Downtime
{ {
/** /**
* @var mixed * Propagate this downtime for all child objects
*/
const TYPE_WITH_CHILDREN = 'AND_PROPAGATE_';
/**
* Propagate this downtime for all child objects as triggered downtime
*/
const TYPE_WITH_CHILDREN_TRIGGERED = 'AND_PROPAGATE_TRIGGERED_';
/**
* Schedule downtime for the services of the given hos
*/
const TYPE_HOST_SVC = 'HOST_SVC';
/**
* Timestamp representing the downtime's start
*
* @var int
*/ */
public $startTime; public $startTime;
/** /**
* @var mixed * Timestamp representing the downtime's end
*
* @var int
*/ */
public $endTime; public $endTime;
/** /**
* @var mixed * Whether this is a fixed downtime
*
* @var boolean
*/ */
private $fixed = false; private $fixed = false;
/** /**
* @var mixed * The duration of the downtime in seconds if flexible
*
* @var int
*/ */
public $duration; public $duration;
/** /**
* @var mixed * The comment object of the downtime
*
* @var Comment
*/ */
public $comment; public $comment;
/** /**
* @param $start * The downtime id that triggers this downtime (0 = no triggered downtime)
* @param $end *
* @param Comment $comment * @var int
* @param int $duration
*/ */
public function __construct($start, $end, Comment $comment, $duration = 0) public $trigger_id = 0;
/**
* Internal information for the exact type of the downtime
*
* E.g. with children, with children and triggered, services etc.
*
* @var string
*/
private $subtype = '';
/**
* Create a new downtime container
*
* @param int $start A timestamp that defines the downtime's start time
* @param int $end A timestamp that defines the downtime's end time
* @param Comment $comment A comment that will be used when scheduling the downtime
* @param int $duration The duration of this downtime in seconds.
* Duration > 0 will make this a flexible downtime
* @param int $trigger_id An id of the downtime that triggers this downtime.
* 0 means this is not a triggered downtime
*/
public function __construct($start, $end, Comment $comment, $duration = 0, $trigger_id = 0)
{ {
$this->startTime = $start; $this->startTime = $start;
$this->endTime = $end; $this->endTime = $end;
$this->comment = $comment; $this->comment = $comment;
if ($duration != 0) { if ($duration == 0) {
$this->fixed = true; $this->fixed = true;
} }
$this->duration = intval($duration); $this->duration = intval($duration);
$this->trigger_id = intval($trigger_id);
} }
/** /**
* @param $type * Return the SCHEDULE_?_DOWNTIME representing this class for the given $type
* @return string *
* @param string $type CommandPipe::TYPE_SERVICE to trigger a service downtime or CommandPipe::TYPE_HOST to
* trigger a host downtime
* @return string A schedule downtime command representing the state of this class
*
*/ */
public function getFormatString($type) public function getFormatString($type)
{ {
return 'SCHEDULE_' . $type . '_DOWNTIME;%s' if ($this->subtype == self::TYPE_HOST_SVC) {
. ($type == CommandPipe::TYPE_SERVICE ? ';%s;' : ';') $type = "";
. $this->startTime . ';' . $this->endTime }
. ';' . ($this->fixed ? '1' : '0') . ';' . $this->duration . ';0;' return 'SCHEDULE_'
. $this->comment->author . ';' . $this->comment->comment; . $this->subtype
. $type
. '_DOWNTIME;'
. '%s;'
. ($type == CommandPipe::TYPE_SERVICE ? '%s;' : '')
. $this->startTime . ';'
. $this->endTime . ';'
. ($this->fixed ? '1' : '0') . ';'
. $this->trigger_id . ';'
. $this->duration . ';'
. $this->comment->author . ';'
. $this->comment->comment;
}
/**
* Set the exact type of this downtime (see the TYPE_ constants)
*
* @param $type The type of to use for this downtime
*/
public function setType($type)
{
$this->subtype = $type;
} }
} }

View File

@ -29,8 +29,7 @@
namespace Icinga\Protocol\Commandpipe\Exception; namespace Icinga\Protocol\Commandpipe\Exception;
/** /**
* Class InvalidCommandException * Exception class for unknown/invalid external commands
* @package Icinga\Protocol\Commandpipe\Exception
*/ */
class InvalidCommandException extends \Exception class InvalidCommandException extends \Exception
{ {

View File

@ -29,8 +29,8 @@
namespace Icinga\Protocol\Commandpipe; namespace Icinga\Protocol\Commandpipe;
/** /**
* Class IComment * Interface flagging a class as being a comment
* @package Icinga\Protocol\Commandpipe *
*/ */
interface IComment interface IComment
{ {

View File

@ -29,60 +29,62 @@
namespace Icinga\Protocol\Commandpipe; namespace Icinga\Protocol\Commandpipe;
/** /**
* Class PropertyModifier * Container class to modify a few monitoring attributes at oncee
* @package Icinga\Protocol\Commandpipe *
*/ */
class PropertyModifier class PropertyModifier
{ {
/** /**
* * Set an attribute to be enabled in the command
*/ */
const STATE_ENABLE = 1; const STATE_ENABLE = 1;
/** /**
* * Set an attribute to be disabled in the command
*/ */
const STATE_DISABLE = 0; const STATE_DISABLE = 0;
/** /**
* * Set an attribute to not be modified in the command
*/ */
const STATE_KEEP = -1; const STATE_KEEP = -1;
/** /**
* * Template for enabling/disabling flap detection
*/ */
const FLAPPING = "%s_FLAP_DETECTION"; const FLAPPING = "%s_FLAP_DETECTION";
/** /**
* * Template for enabling/disabling active checks
*/ */
const ACTIVE = "%s_CHECK"; const ACTIVE = "%s_CHECK";
/** /**
* * Template for enabling/disabling passive checks
*/ */
const PASSIVE = "PASSIVE_%s_CHECKS"; const PASSIVE = "PASSIVE_%s_CHECKS";
/** /**
* * Template for enabling/disabling notification
*/ */
const NOTIFICATIONS = "%s_NOTIFICATIONS"; const NOTIFICATIONS = "%s_NOTIFICATIONS";
/** /**
* * Template for enabling/disabling freshness checks
*/ */
const FRESHNESS = "%s_FRESHNESS_CHECKS"; const FRESHNESS = "%s_FRESHNESS_CHECKS";
/** /**
* * Template for enabling/disabling event handler
*/ */
const EVENTHANDLER = "%s_EVENT_HANDLER"; const EVENTHANDLER = "%s_EVENT_HANDLER";
/** /**
* The state that will be applied when fetching this container for an object
*
* @var array * @var array
*/ */
public $flags = array( private $flags = array(
self::FLAPPING => self::STATE_KEEP, self::FLAPPING => self::STATE_KEEP,
self::ACTIVE => self::STATE_KEEP, self::ACTIVE => self::STATE_KEEP,
self::PASSIVE => self::STATE_KEEP, self::PASSIVE => self::STATE_KEEP,
@ -92,7 +94,9 @@ class PropertyModifier
); );
/** /**
* @param array $flags * Create a new PropertyModified object using the given flags
*
* @param array $flags Flags to enable/disable/keep different monitoring attributes
*/ */
public function __construct(array $flags) public function __construct(array $flags)
{ {
@ -104,8 +108,10 @@ class PropertyModifier
} }
/** /**
* @param $type * Return this object as a template for the given object type
* @return array *
* @param $type Either CommandPipe::TYPE_HOST or CommandPipe::TYPE_SERVICE
* @return array An array of external command templates for the given type representing the containers state
*/ */
public function getFormatString($type) public function getFormatString($type)
{ {

View File

@ -0,0 +1,84 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe\Transport;
use Icinga\Application\Logger;
/**
* CommandPipe Transport class that writes to a file accessible by the filesystem
*/
class LocalPipe implements Transport
{
/**
* The path of the icinga commandpipe
*
* @var String
*/
private $path;
/**
* The mode to use for fopen()
*
* @var string
*/
private $openMode = "w";
/**
* @see Transport::setEndpoint()
*/
public function setEndpoint(\Zend_Config $config)
{
$this->path = isset($config->path) ? $config->path : '/usr/local/icinga/var/rw/icinga.cmd';
}
/**
* @see Transport::send()
*/
public function send($message)
{
Logger::debug('Attempting to send external icinga command %s to local command file ', $message, $this->path);
$file = @fopen($this->path, $this->openMode);
if (!$file) {
throw new \RuntimeException('Could not open icinga pipe at $file : ' . print_r(error_get_last(), true));
}
fwrite($file, '[' . time() . '] ' . $message . PHP_EOL);
Logger::debug('Writing [' . time() . '] ' . $message . PHP_EOL);
fclose($file);
}
/**
* Overwrite the open mode (useful for testing)
*
* @param string $mode A open mode supported by fopen()
*/
public function setOpenMode($mode)
{
$this->openMode = $mode;
}
}

View File

@ -0,0 +1,124 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe\Transport;
use Icinga\Application\Logger;
/**
* Command pipe transport class that uses ssh for connecting to a remote filesystem with the icinga.cmd pipe
* The remote host must have KeyAuth enabled for this user
*
*/
class SecureShell implements Transport
{
/**
* The remote host to connect to
*
* @var string
*/
private $host = 'localhost';
/**
* The location of the icinga pipe on the remote host
*
* @var string
*/
private $path = "/usr/local/icinga/var/rw/icinga.cmd";
/**
* The SSH port of the remote host
*
* @var int
*/
private $port = 22;
/**
* The user to authenticate with on the remote host
*
* @var String
*/
private $user = null;
/**
* @see Transport::setEndpoint()
*
*/
public function setEndpoint(\Zend_Config $config)
{
$this->host = isset($config->host) ? $config->host : "localhost";
$this->port = isset($config->port) ? $config->port : 22;
$this->user = isset($config->user) ? $config->user : null;
$this->password = isset($config->password) ? $config->password : null;
$this->path = isset($config->path) ? $config->path : "/usr/local/icinga/var/rw/icinga.cmd";
}
/**
* @see Transport::send()
*
*/
public function send($command)
{
$retCode = 0;
$output = array();
Logger::debug(
'Icinga instance is on different host, attempting to send command %s via ssh to %s:%s/%s',
$command,
$this->host,
$this->port,
$this->path
);
$hostConnector = $this->user ? $this->user . "@" . $this->host : $this->host;
exec(
'ssh -o BatchMode=yes -o KbdInteractiveAuthentication=no'
. $hostConnector.' -p'.$this->port.' "echo \'['. time() .'] '
. escapeshellcmd(
$command
)
. '\' > '.$this->path.'" > /dev/null 2> /dev/null & ',
$output,
$retCode
);
Logger::debug(
'ssh '.$hostConnector.' -p'.$this->port.' "echo \'['. time() .'] '
. escapeshellcmd(
$command
)
. '\' > '.$this->path.'"'
);
Logger::debug("Return code %s: %s ", $retCode, $output);
if ($retCode != 0) {
$msg = 'Could not send command to remote icinga host: '
. implode(PHP_EOL, $output)
. " (returncode $retCode)";
Logger::error($msg);
throw new \RuntimeException($msg);
}
}
}

View File

@ -0,0 +1,50 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe\Transport;
/**
* Interface for Transport classes handling the concrete access to the command pipe
*
*/
interface Transport
{
/**
* Overwrite the target file of this Transport class using the given config from instances.ini
*
* @param \Zend_Config $config A configuration file containing a 'path' setting
*/
public function setEndpoint(\Zend_Config $config);
/**
* Write the given external command to the command pipe
*
* @param string $message The command to send, without the timestamp (this will be added here)
*/
public function send($message);
}

View File

@ -29,14 +29,15 @@
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Application\Benchmark; use Icinga\Application\Benchmark;
use Icinga\Application\Icinga;
use Icinga\Backend; use Icinga\Backend;
use Icinga\Application\Config; use Icinga\Application\Config;
use Icinga\Application\Logger;
use Icinga\Authentication\Manager; use Icinga\Authentication\Manager;
use Icinga\Web\Form; use Icinga\Web\Form;
use Icinga\Web\ModuleActionController; use Icinga\Web\ModuleActionController;
use Icinga\Protocol\Commandpipe\Comment; use Icinga\Protocol\Commandpipe\Comment;
use Icinga\Protocol\Commandpipe\CommandPipe; use Icinga\Protocol\Commandpipe\CommandPipe;
use Icinga\Protocol\Commandpipe\Acknowledgement;
use Icinga\Exception\ConfigurationError; use Icinga\Exception\ConfigurationError;
use Icinga\Exception\MissingParameterException; use Icinga\Exception\MissingParameterException;
use Monitoring\Form\Command\AcknowledgeForm; use Monitoring\Form\Command\AcknowledgeForm;
@ -97,18 +98,19 @@ class Monitoring_CommandController extends ModuleActionController
{ {
if ($this->issetForm()) { if ($this->issetForm()) {
if ($this->form->isPostAndValid()) { if ($this->form->isPostAndValid()) {
$this->_helper->viewRenderer->setNoRender(true); $this->_helper->viewRenderer->setNoRender(true);
$this->_helper->layout()->disableLayout(); $this->_helper->layout()->disableLayout();
} }
$this->view->form = $this->form; $this->view->form = $this->form;
} }
parent::postDispatch(); parent::postDispatch();
} }
/** /**
* Controller configuration * Controller configuration
*
* @throws Icinga\Exception\ConfigurationError * @throws Icinga\Exception\ConfigurationError
*/ */
public function init() public function init()
@ -116,9 +118,7 @@ class Monitoring_CommandController extends ModuleActionController
if ($this->_request->isPost()) { if ($this->_request->isPost()) {
$instance = $this->_request->getPost("instance"); $instance = $this->_request->getPost("instance");
$targetConfig = Config::module('monitoring', 'instances'); $targetConfig = Config::module('monitoring', 'instances');
if ($instance) { if ($instance) {
if ($targetConfig->get($instance)) { if ($targetConfig->get($instance)) {
$this->target = new CommandPipe($targetConfig->get($instance)); $this->target = new CommandPipe($targetConfig->get($instance));
@ -137,37 +137,60 @@ class Monitoring_CommandController extends ModuleActionController
} }
if ($this->getRequest()->getActionName() !== 'list') { if ($this->getRequest()->getActionName() !== 'list') {
// Reduce template writing mess
$this->_helper->viewRenderer->setRender(self::DEFAULT_VIEW_SCRIPT); $this->_helper->viewRenderer->setRender(self::DEFAULT_VIEW_SCRIPT);
} }
} }
/** /**
* Retrieve all existing targets for host- and service combination * Retrieve all existing targets for host- and service combination
* @param string $hostname *
* @param string $servicename * @param $hostOnly Ignore the service parameters
* @return array * (for example when using commands that only make sense for hosts)
*
* @return array Array of monitoring objects
*
* @throws Icinga\Exception\MissingParameterException * @throws Icinga\Exception\MissingParameterException
*/ */
private function selectCommandTargets($hostname, $servicename = null) private function selectCommandTargets($hostOnly = false)
{ {
$target = "hostlist"; $query = null;
$fields = array(
'host_name',
'host_state'
);
try {
$hostname = $this->getParam('host', null);
$servicename = $this->getParam('service', null);
$filter = array(); $filter = array();
if (!$hostname && !$servicename) { if (!$hostname && !$servicename) {
throw new MissingParameterException("Missing host and service definition"); throw new MissingParameterException("No target given for this command");
} }
if ($hostname) { if ($hostname) {
$filter["host_name"] = $hostname; $filter["host_name"] = $hostname;
} }
if ($servicename) { if ($servicename && !$hostOnly) {
$filter["service_description"] = $servicename; $filter["service_description"] = $servicename;
$target = "servicelist"; $fields[] = "service_description";
$fields[] = "service_state";
}
;
$query = Backend::getInstance()->select()->from("status", $fields);
return $query->applyFilters($filter)->fetchAll();
} catch (\Exception $e) {
Logger::error(
"CommandController: SQL Query '%s' failed (message %s) ",
$query ? (string) $query->getQuery()->dump() : '--', $e->getMessage()
);
return array();
} }
return Backend::getInstance()->select()->from($target)->applyFilters($filter)->fetchAll();
} }
/** /**
* Displays a list of all commands * Displays a list of all commands
*
* This method uses reflection on the sourcecode to determine all *Action classes and return
* a list of them (ignoring the listAction)
*
*/ */
public function listAction() public function listAction()
{ {
@ -183,16 +206,48 @@ class Monitoring_CommandController extends ModuleActionController
$this->view->commands = $commands; $this->view->commands = $commands;
} }
/**
* Tell the controller that at least one of the parameters in $supported is required to be availabe
*
* @param array $supported An array of properties to check for existence in the POST or GET parameter list
*
* @throws Exception When non of the supported parameters is given
*/
private function setSupportedParameters(array $supported)
{
$given = array_intersect_key(array_flip($supported), $this->getRequest()->getParams());
if (empty($given)) {
throw new \Exception('Missing parameter, supported: '.implode(', ', $supported));
}
if (isset($given["host"])) {
$this->view->objects = $this->selectCommandTargets(!in_array("service", $supported));
if (empty($this->view->objects)) {
throw new \Exception("No objects found for your command");
}
} else if (in_array("downtimeid", $supported)) {
$this->view->objects = array();
$downtimes = $this->getParam("downtimeid");
if (!is_array($downtimes)) {
$downtimes = array($downtimes);
}
foreach ($downtimes as $downtimeId) {
$this->view->objects[] = (object) array("downtime_id" => $downtimeId);
}
}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Commands for hosts / services // Commands for hosts / services
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Handle command disableactivechecks * Handle command disableactivechecks
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function disableactivechecksAction() public function disableactivechecksAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Disable active checks')); $form->setSubmitLabel(t('Disable active checks'));
@ -200,16 +255,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->disableActiveChecks($this->view->objects);
} }
} }
/** /**
* Handle command enableactivechecks * Handle command enableactivechecks
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function enableactivechecksAction() public function enableactivechecksAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Enable active checks')); $form->setSubmitLabel(t('Enable active checks'));
@ -217,32 +273,34 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->enableActiveChecks($this->view->objects);
} }
} }
/** /**
* Handle command reschedulenextcheck * Handle command reschedulenextcheck
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function reschedulenextcheckAction() public function reschedulenextcheckAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new RescheduleNextCheckForm(); $form = new RescheduleNextCheckForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->scheduleCheck($this->view->objects);
} }
} }
/** /**
* Handle command submitpassivecheckresult * Handle command submitpassivecheckresult
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function submitpassivecheckresultAction() public function submitpassivecheckresultAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$type = SubmitPassiveCheckResultForm::TYPE_SERVICE; $type = SubmitPassiveCheckResultForm::TYPE_SERVICE;
$form = new SubmitPassiveCheckResultForm(); $form = new SubmitPassiveCheckResultForm();
@ -252,16 +310,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->submitCheckResult($this->view->objects, $form->getState(), $form->getOutput(), $form->getPerformancedata());
} }
} }
/** /**
* Handle command stopobsessing * Handle command stopobsessing
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function stopobsessingAction() public function stopobsessingAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Stop obsessing')); $form->setSubmitLabel(t('Stop obsessing'));
@ -269,16 +328,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->stopObsessing($this->view->objects);
} }
} }
/** /**
* Handle command startobsessing * Handle command startobsessing
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function startobsessingAction() public function startobsessingAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Start obsessing')); $form->setSubmitLabel(t('Start obsessing'));
@ -286,16 +346,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->startObsessing($this->view->objects);
} }
} }
/** /**
* Handle command stopacceptingpassivechecks * Handle command stopacceptingpassivechecks
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function stopacceptingpassivechecksAction() public function stopacceptingpassivechecksAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Stop accepting passive checks')); $form->setSubmitLabel(t('Stop accepting passive checks'));
@ -303,16 +364,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->disablePassiveChecks($this->view->objects);
} }
} }
/** /**
* Handle command startacceptingpassivechecks * Handle command startacceptingpassivechecks
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function startacceptingpassivechecksAction() public function startacceptingpassivechecksAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Start accepting passive checks')); $form->setSubmitLabel(t('Start accepting passive checks'));
@ -320,16 +382,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->enableActiveChecks($this->view->objects);
} }
} }
/** /**
* Handle command disablenotifications * Handle command disablenotifications
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function disablenotificationsAction() public function disablenotificationsAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Disable notifications')); $form->setSubmitLabel(t('Disable notifications'));
@ -337,13 +400,13 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->disableNotifications($this->view->objects);
} }
} }
/** /**
* Handle command enablenotifications * Handle command enablenotifications
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function enablenotificationsAction() public function enablenotificationsAction()
{ {
@ -354,63 +417,73 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->enableNotifications($this->view->objects);
} }
} }
/** /**
* Handle command sendcustomnotification * Handle command sendcustomnotification
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function sendcustomnotificationAction() public function sendcustomnotificationAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new CustomNotificationForm(); $form = new CustomNotificationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $author = $this->getRequest()->getUser()->getUsername();
$this->target->sendCustomNotification(
$this->view->objects,
new Comment($author, $form->getComment()),
$form->getOptions()
);
} }
} }
/** /**
* Handle command scheduledowntime * Handle command scheduledowntime
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function scheduledowntimeAction() public function scheduledowntimeAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ScheduleDowntimeForm(); $form = new ScheduleDowntimeForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setWithChildren(false); $form->setWithChildren(false);
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->scheduleDowntime($this->view->objects, $form->getDowntime());
} }
} }
/** /**
* Handle command scheduledowntimeswithchildren * Handle command scheduledowntimeswithchildren
*
* @throws Icinga\Exception\ProgrammingError * @throws Icinga\Exception\ProgrammingError
*/ */
public function scheduledowntimeswithchildrenAction() public function scheduledowntimeswithchildrenAction()
{ {
$this->setSupportedParameters(array('host'));
$form = new ScheduleDowntimeForm(); $form = new ScheduleDowntimeForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setWithChildren(true); $form->setWithChildren(true);
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->scheduleDowntime($this->view->objects, $form->getDowntime());
} }
} }
/** /**
* Handle command removedowntimeswithchildren * Handle command removedowntimeswithchildren
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function removedowntimeswithchildrenAction() public function removedowntimeswithchildrenAction()
{ {
$this->setSupportedParameters(array('host'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Remove downtime(s)')); $form->setSubmitLabel(t('Remove downtime(s)'));
@ -418,16 +491,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->removeDowntime($this->view->objects);
} }
} }
/** /**
* Handle command disablenotificationswithchildren * Handle command disablenotificationswithchildren
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function disablenotificationswithchildrenAction() public function disablenotificationswithchildrenAction()
{ {
$this->setSupportedParameters(array('host'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Disable notifications')); $form->setSubmitLabel(t('Disable notifications'));
@ -435,16 +509,18 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->disableNotifications($this->view->objects);
$this->target->disableNotificationsForServices($this->view->objects);
} }
} }
/** /**
* Handle command enablenotificationswithchildren * Handle command enablenotificationswithchildren
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function enablenotificationswithchildrenAction() public function enablenotificationswithchildrenAction()
{ {
$this->setSupportedParameters(array('host'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Enable notifications')); $form->setSubmitLabel(t('Enable notifications'));
@ -452,16 +528,18 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->enableNotifications($this->view->objects);
$this->target->enableNotificationsForServices($this->view->objects);
} }
} }
/** /**
* Handle command reschedulenextcheckwithchildren * Handle command reschedulenextcheckwithchildren
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function reschedulenextcheckwithchildrenAction() public function reschedulenextcheckwithchildrenAction()
{ {
$this->setSupportedParameters(array('host'));
$form = new RescheduleNextCheckForm(); $form = new RescheduleNextCheckForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
@ -470,16 +548,23 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); if ($form->isForced()) {
$this->target->scheduleForcedCheck($this->view->objects, time());
$this->target->scheduleForcedCheck($this->view->objects, time(), true);
} else {
$this->target->scheduleCheck($this->view->objects, time());
$this->target->scheduleCheck($this->view->objects, time(), true);
}
} }
} }
/** /**
* Handle command disableactivecheckswithchildren * Handle command disableactivecheckswithchildren
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function disableactivecheckswithchildrenAction() public function disableactivecheckswithchildrenAction()
{ {
$this->setSupportedParameters(array('host'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Disable active checks')); $form->setSubmitLabel(t('Disable active checks'));
@ -487,16 +572,18 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->disableActiveChecks($this->view->objects);
$this->target->disableActiveChecksWithChildren($this->view->objects);
} }
} }
/** /**
* Handle command enableactivecheckswithchildren * Handle command enableactivecheckswithchildren
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function enableactivecheckswithchildrenAction() public function enableactivecheckswithchildrenAction()
{ {
$this->setSupportedParameters(array('host'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Enable active checks')); $form->setSubmitLabel(t('Enable active checks'));
@ -504,16 +591,18 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->enableActiveChecks($this->view->objects);
$this->target->enableActiveChecksWithChildren($this->view->objects);
} }
} }
/** /**
* Handle command disableeventhandler * Handle command disableeventhandler
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function disableeventhandlerAction() public function disableeventhandlerAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Disable event handler')); $form->setSubmitLabel(t('Disable event handler'));
@ -521,16 +610,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->disableEventHandler($this->view->objects);
} }
} }
/** /**
* Handle command enableeventhandler * Handle command enableeventhandler
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function enableeventhandlerAction() public function enableeventhandlerAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Enable event handler')); $form->setSubmitLabel(t('Enable event handler'));
@ -538,16 +628,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->enableEventHandler($this->view->objects);
} }
} }
/** /**
* Handle command disableflapdetection * Handle command disableflapdetection
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function disableflapdetectionAction() public function disableflapdetectionAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Disable flapping detection')); $form->setSubmitLabel(t('Disable flapping detection'));
@ -555,16 +646,17 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->disableFlappingDetection($this->view->objects);
} }
} }
/** /**
* Handle command enableflapdetection * Handle command enableflapdetection
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function enableflapdetectionAction() public function enableflapdetectionAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Enable flapping detection')); $form->setSubmitLabel(t('Enable flapping detection'));
@ -572,32 +664,34 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->enableFlappingDetection($this->view->objects);
} }
} }
/** /**
* Handle command addcomment * Handle command addcomment
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function addcommentAction() public function addcommentAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new CommentForm(); $form = new CommentForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->addComment($this->view->objects, $form->getComment());
} }
} }
/** /**
* Handle command resetattributes * Handle command resetattributes
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function resetattributesAction() public function resetattributesAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Reset attributes')); $form->setSubmitLabel(t('Reset attributes'));
@ -605,32 +699,34 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->resetAttributes($this->view->objects);
} }
} }
/** /**
* Handle command acknowledgeproblem * Handle command acknowledgeproblem
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function acknowledgeproblemAction() public function acknowledgeproblemAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new AcknowledgeForm(); $form = new AcknowledgeForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->acknowledge($this->view->objects, $form->getAcknowledgement());
} }
} }
/** /**
* Handle command removeacknowledgement * Handle command removeacknowledgement
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function removeacknowledgementAction() public function removeacknowledgementAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new ConfirmationForm(); $form = new ConfirmationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setSubmitLabel(t('Remove problem acknowledgement')); $form->setSubmitLabel(t('Remove problem acknowledgement'));
@ -638,32 +734,34 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->removeAcknowledge($this->view->objects);
} }
} }
/** /**
* Handle command delaynotification * Handle command delaynotification
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function delaynotificationAction() public function delaynotificationAction()
{ {
$this->setSupportedParameters(array('host', 'service'));
$form = new DelayNotificationForm(); $form = new DelayNotificationForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->delayNotification($this->view->objects, $form->getDelayTime());
} }
} }
/** /**
* Handle command removedowntime * Handle command removedowntime
* @throws Icinga\Exception\ProgrammingError *
*/ */
public function removedowntimeAction() public function removedowntimeAction()
{ {
$this->setSupportedParameters(array('downtimeid'));
$form = new ConfirmationWithIdentifierForm(); $form = new ConfirmationWithIdentifierForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
@ -675,7 +773,7 @@ class Monitoring_CommandController extends ModuleActionController
$this->setForm($form); $this->setForm($form);
if ($form->isPostAndValid() === true) { if ($form->isPostAndValid() === true) {
throw new \Icinga\Exception\ProgrammingError('Command sender not implemented: '. __FUNCTION__); $this->target->removeDowntime($this->view->objects);
} }
} }
} }

View File

@ -32,7 +32,8 @@ use Icinga\Web\Form\Element\DateTime;
use \DateTime as PhpDateTime; use \DateTime as PhpDateTime;
use \DateInterval; use \DateInterval;
use Icinga\Web\Form\Element\Note; use Icinga\Web\Form\Element\Note;
use Icinga\Protocol\Commandpipe\Acknowledgement;
use Icinga\Protocol\Commandpipe\Comment;
/** /**
* Form for acknowledge commands * Form for acknowledge commands
*/ */
@ -142,4 +143,24 @@ class AcknowledgeForm extends ConfirmationForm
$expireTime->addValidator($this->createDateTimeValidator(), true); $expireTime->addValidator($this->createDateTimeValidator(), true);
} }
} }
public function getAcknowledgement()
{
$expireTime = -1;
if ($this->getValue('expire')) {
$time = new PhpDateTime($this->getValue('expiretime'));
$expireTime = $time->getTimestamp();
}
return new Acknowledgement(
new Comment(
$this->getAuthorName(),
$this->getValue('comment'),
$this->getValue('persistent')
),
$this->getValue('notify'),
$expireTime,
$this->getValue('sticky')
);
}
} }

View File

@ -28,6 +28,7 @@
namespace Monitoring\Form\Command; namespace Monitoring\Form\Command;
use Icinga\Protocol\Commandpipe\Comment;
/** /**
* Form for adding comment commands * Form for adding comment commands
*/ */
@ -64,4 +65,9 @@ class CommentForm extends ConfirmationForm
parent::create(); parent::create();
} }
public function getComment()
{
return new Comment($this->getAuthorName(), $this->getValue('comment'), $this->getValue('persistent'));
}
} }

View File

@ -68,12 +68,14 @@ class ConfirmationForm extends Form
/** /**
* Array of messages * Array of messages
*
* @var string[] * @var string[]
*/ */
private $notes = array(); private $notes = array();
/** /**
* Setter for cancel label * Setter for cancel label
*
* @param string $cancelLabel * @param string $cancelLabel
*/ */
public function setCancelLabel($cancelLabel) public function setCancelLabel($cancelLabel)
@ -83,6 +85,7 @@ class ConfirmationForm extends Form
/** /**
* Getter for cancel label * Getter for cancel label
*
* @return string * @return string
*/ */
public function getCancelLabel() public function getCancelLabel()
@ -92,6 +95,7 @@ class ConfirmationForm extends Form
/** /**
* Setter for submit label * Setter for submit label
*
* @param string $submitLabel * @param string $submitLabel
*/ */
public function setSubmitLabel($submitLabel) public function setSubmitLabel($submitLabel)
@ -101,6 +105,7 @@ class ConfirmationForm extends Form
/** /**
* Getter for submit label * Getter for submit label
*
* @return string * @return string
*/ */
public function getSubmitLabel() public function getSubmitLabel()
@ -110,6 +115,7 @@ class ConfirmationForm extends Form
/** /**
* Add message to stack * Add message to stack
*
* @param string $message * @param string $message
*/ */
public function addNote($message) public function addNote($message)
@ -119,6 +125,7 @@ class ConfirmationForm extends Form
/** /**
* Purge messages from stack * Purge messages from stack
*
*/ */
public function clearNotes() public function clearNotes()
{ {
@ -127,6 +134,7 @@ class ConfirmationForm extends Form
/** /**
* Getter for notes * Getter for notes
*
* @return string[] * @return string[]
*/ */
public function getNotes() public function getNotes()
@ -148,6 +156,7 @@ class ConfirmationForm extends Form
/** /**
* Add elements to this form (used by extending classes) * Add elements to this form (used by extending classes)
*
* @see Form::create * @see Form::create
*/ */
protected function create() protected function create()
@ -191,15 +200,19 @@ class ConfirmationForm extends Form
/** /**
* Get the author name * Get the author name
* TODO(mh): This should work on the request, at present it's fix
*/ */
protected function getAuthorName() protected function getAuthorName()
{ {
return 'Iwan IV. Wassiljewitsch, der Schreckliche'; if (is_a($this->getRequest(), "Zend_Controller_Request_HttpTestCase")) {
return "Test user";
}
return $this->getRequest()->getUser()->getUsername();
} }
/** /**
* Creator for author field * Creator for author field
*
* @return Zend_Form_Element_Hidden * @return Zend_Form_Element_Hidden
*/ */
protected function createAuthorField() protected function createAuthorField()

View File

@ -73,4 +73,21 @@ class CustomNotificationForm extends ConfirmationForm
parent::create(); parent::create();
} }
public function getComment()
{
return $this->getValue('comment');
}
public function getOptions()
{
$value = 0;
if ($this->getValue('force')) {
$value |= 2;
}
if ($this->getValue('broadcast')) {
$value |= 1;
}
return $value;
}
} }

View File

@ -70,4 +70,9 @@ class DelayNotificationForm extends ConfirmationForm
parent::create(); parent::create();
} }
public function getDelayTime()
{
return $this->getValue('minutes')*60;
}
} }

View File

@ -79,4 +79,9 @@ class RescheduleNextCheckForm extends WithChildrenCommandForm
parent::create(); parent::create();
} }
public function isForced()
{
return $this->getValue('forcecheck') == true;
}
} }

View File

@ -29,6 +29,8 @@
namespace Monitoring\Form\Command; namespace Monitoring\Form\Command;
use Icinga\Web\Form\Element\DateTime; use Icinga\Web\Form\Element\DateTime;
use Icinga\Protocol\Commandpipe\Downtime;
use Icinga\Protocol\Commandpipe\Comment;
use \DateTime as PhpDateTime; use \DateTime as PhpDateTime;
use \DateInterval; use \DateInterval;
use \Zend_Form_Element_Text; use \Zend_Form_Element_Text;
@ -58,6 +60,7 @@ class ScheduleDowntimeForm extends WithChildrenCommandForm
/** /**
* Build an array of timestamps * Build an array of timestamps
*
* @return string[] * @return string[]
*/ */
private function generateDefaultTimestamps() private function generateDefaultTimestamps()
@ -76,6 +79,7 @@ class ScheduleDowntimeForm extends WithChildrenCommandForm
/** /**
* Generate translated multi options based on type constants * Generate translated multi options based on type constants
*
* @return array * @return array
*/ */
private function getDowntimeTypeOptions() private function getDowntimeTypeOptions()
@ -88,6 +92,7 @@ class ScheduleDowntimeForm extends WithChildrenCommandForm
/** /**
* Interface method to build the form * Interface method to build the form
*
* @see ConfirmationForm::create * @see ConfirmationForm::create
*/ */
protected function create() protected function create()
@ -104,6 +109,10 @@ class ScheduleDowntimeForm extends WithChildrenCommandForm
) )
); );
/**
* @TODO: Display downtime list (Bug #4496)
*
*/
$this->addElement( $this->addElement(
'text', 'text',
'triggered', 'triggered',
@ -242,6 +251,7 @@ class ScheduleDowntimeForm extends WithChildrenCommandForm
/** /**
* Change validators at runtime * Change validators at runtime
*
* @see Form::preValidation * @see Form::preValidation
* @param array $data * @param array $data
*/ */
@ -265,4 +275,45 @@ class ScheduleDowntimeForm extends WithChildrenCommandForm
$minutes->addValidator($greaterThanValidator, true); $minutes->addValidator($greaterThanValidator, true);
} }
} }
/**
* Return the downtime submitted in this form
*
* @return Downtime
*/
public function getDowntime()
{
$comment = new Comment(
$this->getRequest()->getUser()->getUsername(),
$this->getValue('comment')
);
$duration = 0;
if ($this->getValue('type') === self::TYPE_FLEXIBLE) {
$duration = ($this->getValue('hours')*3600) + ($this->getValue('minutes')*60);
}
$starttime = new PhpDateTime($this->getValue('starttime'));
$endtime = new PhpDateTime($this->getValue('endtime'));
$downtime = new Downtime(
$starttime->getTimestamp(),
$endtime->getTimestamp(),
$comment,
$duration,
$this->getValue('triggered')
);
if (! $this->getWithChildren()) {
switch ($this->getValue('childobjects')) {
case 1:
$downtime->setType(Downtime::TYPE_WITH_CHILDREN_TRIGGERED);
break;
case 2:
$downtime->setType(Downtime::TYPE_WITH_CHILDREN);
break;
}
} else {
$downtime->setType(Downtime::TYPE_HOST_SVC);
}
return $downtime;
}
} }

View File

@ -168,4 +168,20 @@ class SubmitPassiveCheckResultForm extends ConfirmationForm
parent::create(); parent::create();
} }
public function getState()
{
return intval($this->getValue('pluginstate'));
}
public function getOutput()
{
return $this->getValue('checkoutput');
}
public function getPerformancedata()
{
return $this->getValue('performancedata');
}
} }

View File

@ -39,7 +39,7 @@ class Zend_View_Helper_MonitoringFlags extends Zend_View_Helper_Abstract
private static $keys = array( private static $keys = array(
'passive_checks_enabled' => 'Passive checks', 'passive_checks_enabled' => 'Passive checks',
'active_checks_enabled' => 'Active checks', 'active_checks_enabled' => 'Active checks',
'obsess_over_host' => 'Obsessing', 'obsessing' => 'Obsessing',
'notifications_enabled' => 'Notifications', 'notifications_enabled' => 'Notifications',
'event_handler_enabled' => 'Event handler', 'event_handler_enabled' => 'Event handler',
'flap_detection_enabled' => 'Flap detection', 'flap_detection_enabled' => 'Flap detection',

View File

@ -1,4 +1,30 @@
<?php if (isset($this->objects) && !empty($this->objects) && isset($this->objects[0]->host_name)): ?>
<table class="table table-bordered table-striped table-condensed">
<legend>Affected objects</legend>
<thead>
<tr>
<th>Host name</th>
<th>Service name</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->objects as $object): ?>
<tr>
<td><?= $object->host_name; ?></td>
<td><?= (isset($object->service_description) ? $object->service_description : ''); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php if ($this->form): ?>
<div style="border: 1px #cc0000 solid; padding: 5px; margin: 10px 0 0 10px; max-width: 600px;"> <div style="border: 1px #cc0000 solid; padding: 5px; margin: 10px 0 0 10px; max-width: 600px;">
<?= $this->form; ?> <?= $this->form; ?>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<?php endif; ?>

View File

@ -0,0 +1,37 @@
# The instance.ini configuration file
## Abstract
The instance.ini defines how icingaweb accesses the command pipe of your icinga process in order to submit external
commands. When you are at the root of your icingaweb installation you can find it under ./config/modules/monitoring/instances.ini.
## Syntax
You can define multiple instances in the instances.ini, icingaweb will use the first one as the default instance.
Every instance starts with a section header containing the name of the instance, followed by the config directives for
this instance in the standard ini format used by icingaweb.
## Using a local icinga pipe
A local icinga instance can be easily setup and only requires the 'path' parameter:
[icinga]
path=/usr/local/icinga/var/rw/icinga.cmd
When sending commands to the icinga instance, icingaweb just opens the file found underneath 'path' and writes the external
command to it.
## Using ssh for accessing an icinga pipe
When providing at least a host directive to the instances.ini, SSH will be used for accessing the pipe. You must have
setup key authentication at the endpoint and allow your icingweb's user to access the machine without a password at this time:
[icinga]
path=/usr/local/icinga/var/rw/icinga.cmd ; the path on the remote machine where the icinga.cmd can be found
host=my.remote.machine.com ; the hostname or address of the remote machine
port=22 ; the port to use (22 if none is given)
user=jdoe ; the user to authenticate with

View File

@ -149,7 +149,7 @@ class AbstractBackend implements DatasourceInterface
'host_scheduled_downtime_depth', 'host_scheduled_downtime_depth',
'host_failure_prediction_enabled', 'host_failure_prediction_enabled',
'host_process_performance_data', 'host_process_performance_data',
'host_obsess_over_host', 'host_obsessing',
'host_modified_host_attributes', 'host_modified_host_attributes',
'host_event_handler', 'host_event_handler',
'host_check_command', 'host_check_command',
@ -230,7 +230,7 @@ class AbstractBackend implements DatasourceInterface
'service_scheduled_downtime_depth', 'service_scheduled_downtime_depth',
'service_failure_prediction_enabled', 'service_failure_prediction_enabled',
'service_process_performance_data', 'service_process_performance_data',
'service_obsess_over_service', 'service_obsessing',
'service_modified_service_attributes', 'service_modified_service_attributes',
'service_event_handler', 'service_event_handler',
'service_check_command', 'service_check_command',

View File

@ -60,7 +60,7 @@ class StatusQuery extends AbstractQuery
'host_scheduled_downtime_depth' => 'hs.scheduled_downtime_depth', 'host_scheduled_downtime_depth' => 'hs.scheduled_downtime_depth',
'host_failure_prediction_enabled' => 'hs.failure_prediction_enabled', 'host_failure_prediction_enabled' => 'hs.failure_prediction_enabled',
'host_process_performance_data' => 'hs.process_performance_data', 'host_process_performance_data' => 'hs.process_performance_data',
'host_obsess_over_host' => 'hs.obsess_over_host', 'host_obsessing' => 'hs.obsess_over_host',
'host_modified_host_attributes' => 'hs.modified_host_attributes', 'host_modified_host_attributes' => 'hs.modified_host_attributes',
'host_event_handler' => 'hs.event_handler', 'host_event_handler' => 'hs.event_handler',
'host_check_command' => 'hs.check_command', 'host_check_command' => 'hs.check_command',
@ -160,7 +160,7 @@ class StatusQuery extends AbstractQuery
'service_scheduled_downtime_depth' => 'ss.scheduled_downtime_depth', 'service_scheduled_downtime_depth' => 'ss.scheduled_downtime_depth',
'service_failure_prediction_enabled' => 'ss.failure_prediction_enabled', 'service_failure_prediction_enabled' => 'ss.failure_prediction_enabled',
'service_process_performance_data' => 'ss.process_performance_data', 'service_process_performance_data' => 'ss.process_performance_data',
'service_obsess_over_service' => 'ss.obsess_over_service', 'service_obsessing' => 'ss.obsess_over_service',
'service_modified_service_attributes' => 'ss.modified_service_attributes', 'service_modified_service_attributes' => 'ss.modified_service_attributes',
'service_event_handler' => 'ss.event_handler', 'service_event_handler' => 'ss.event_handler',
'service_check_command' => 'ss.check_command', 'service_check_command' => 'ss.check_command',

View File

@ -729,8 +729,8 @@ class Meta
} else { } else {
unset($commands[self::CMD_START_ACCEPTING_PASSIVE_CHECKS]); unset($commands[self::CMD_START_ACCEPTING_PASSIVE_CHECKS]);
} }
$obsess = 'obsess_over_'.$type;
if ($object->$obsess === '1') { if ($object->obsessing === '1') {
unset($commands[self::CMD_START_OBSESSING]); unset($commands[self::CMD_START_OBSESSING]);
} else { } else {
unset($commands[self::CMD_STOP_OBSESSING]); unset($commands[self::CMD_STOP_OBSESSING]);

View File

@ -54,7 +54,7 @@ class HostStruct extends \stdClass
public $host_scheduled_downtime_depth = '1'; public $host_scheduled_downtime_depth = '1';
public $host_failure_prediction_enabled = '1'; public $host_failure_prediction_enabled = '1';
public $host_process_performance_data = '1'; public $host_process_performance_data = '1';
public $host_obsess_over_host = '1'; public $host_obsessing = '1';
public $host_modified_host_attributes = '14'; public $host_modified_host_attributes = '14';
public $host_event_handler = ''; public $host_event_handler = '';
public $host_normal_check_interval = '5'; public $host_normal_check_interval = '5';

View File

@ -13,7 +13,7 @@ class MonitoringFlagsTest extends \PHPUnit_Framework_TestCase
$testArray = array( $testArray = array(
'host_passive_checks_enabled' => '0', 'host_passive_checks_enabled' => '0',
'host_active_checks_enabled' => '0', 'host_active_checks_enabled' => '0',
'host_obsess_over_host' => '1', 'host_obsessing' => '1',
'host_notifications_enabled' => '0', 'host_notifications_enabled' => '0',
'host_event_handler_enabled' => '1', 'host_event_handler_enabled' => '1',
'host_flap_detection_enabled' => '1', 'host_flap_detection_enabled' => '1',
@ -41,7 +41,7 @@ class MonitoringFlagsTest extends \PHPUnit_Framework_TestCase
$testArray = array( $testArray = array(
'service_passive_checks_enabled' => '0', 'service_passive_checks_enabled' => '0',
'service_active_checks_enabled' => '1', 'service_active_checks_enabled' => '1',
'service_obsess_over_host' => '0', 'service_obsessing' => '0',
'service_notifications_enabled' => '1', 'service_notifications_enabled' => '1',
'service_event_handler_enabled' => '1', 'service_event_handler_enabled' => '1',
'service_flap_detection_enabled' => '0', 'service_flap_detection_enabled' => '0',
@ -68,7 +68,7 @@ class MonitoringFlagsTest extends \PHPUnit_Framework_TestCase
{ {
$testArray = array( $testArray = array(
'service_active_checks_enabled' => '1', 'service_active_checks_enabled' => '1',
'service_obsess_over_host' => '1', 'service_obsessing' => '1',
'DING DING' => '$$$', 'DING DING' => '$$$',
'DONG DONG' => '###' 'DONG DONG' => '###'
); );

View File

@ -50,7 +50,7 @@ class HostStruct4Properties extends \stdClass
public $host_scheduled_downtime_depth = '1'; public $host_scheduled_downtime_depth = '1';
public $host_failure_prediction_enabled = '1'; public $host_failure_prediction_enabled = '1';
public $host_process_performance_data = '1'; public $host_process_performance_data = '1';
public $host_obsess_over_host = '1'; public $host_obsessing = '1';
public $host_modified_host_attributes = '14'; public $host_modified_host_attributes = '14';
public $host_event_handler = ''; public $host_event_handler = '';
public $host_normal_check_interval = '5'; public $host_normal_check_interval = '5';

View File

@ -51,7 +51,7 @@ class HostStruct extends \stdClass
public $host_scheduled_downtime_depth = '1'; public $host_scheduled_downtime_depth = '1';
public $host_failure_prediction_enabled = '1'; public $host_failure_prediction_enabled = '1';
public $host_process_performance_data = '1'; public $host_process_performance_data = '1';
public $host_obsess_over_host = '1'; public $host_obsessing = '1';
public $host_modified_host_attributes = '14'; public $host_modified_host_attributes = '14';
public $host_event_handler = ''; public $host_event_handler = '';
public $host_normal_check_interval = '5'; public $host_normal_check_interval = '5';
@ -158,7 +158,7 @@ class MetaTest extends \PHPUnit_Framework_TestCase
$object = new HostStruct(); $object = new HostStruct();
$object->host_obsess_over_host = '0'; $object->host_obsessing = '0';
$object->host_flap_detection_enabled = '0'; $object->host_flap_detection_enabled = '0';
$object->host_active_checks_enabled = '0'; $object->host_active_checks_enabled = '0';

View File

@ -0,0 +1,34 @@
<?php
/**
* Created by JetBrains PhpStorm.
* User: moja
* Date: 7/31/13
* Time: 1:29 PM
* To change this template use File | Settings | File Templates.
*/
namespace Tests\Icinga\Protocol\Commandpipe;
require_once("./library/Icinga/LibraryLoader.php");
use Test\Icinga\LibraryLoader;
class CommandPipeLoader extends LibraryLoader {
public static function requireLibrary()
{
require_once("Zend/Config.php");
require_once("Zend/Log.php");
require_once("../../library/Icinga/Application/Logger.php");
require_once("../../library/Icinga/Protocol/Commandpipe/IComment.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Comment.php");
require_once("../../library/Icinga/Protocol/Commandpipe/CommandPipe.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Acknowledgement.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Downtime.php");
require_once("../../library/Icinga/Protocol/Commandpipe/PropertyModifier.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Exception/InvalidCommandException.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Transport/Transport.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Transport/SecureShell.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Transport/LocalPipe.php");
}
}

View File

@ -1,35 +1,45 @@
<?php <?php
namespace Tests\Icinga\Protocol\Commandpipe; namespace Tests\Icinga\Protocol\Commandpipe;
require_once(__DIR__.'/CommandPipeLoader.php');
CommandPipeLoader::requireLibrary();
use Icinga\Protocol\Commandpipe\Comment as Comment; use Icinga\Protocol\Commandpipe\Comment as Comment;
use Icinga\Protocol\Commandpipe\Acknowledgement as Acknowledgement; use Icinga\Protocol\Commandpipe\Acknowledgement as Acknowledgement;
use Icinga\Protocol\Commandpipe\Downtime as Downtime; use Icinga\Protocol\Commandpipe\Downtime as Downtime;
use Icinga\Protocol\Commandpipe\Commandpipe as Commandpipe; use Icinga\Protocol\Commandpipe\Commandpipe as Commandpipe;
use \Icinga\Protocol\Commandpipe\PropertyModifier as MONFLAG; use \Icinga\Protocol\Commandpipe\PropertyModifier as MONFLAG;
use Icinga\Protocol\Ldap\Exception;
require_once("Zend/Config.php");
require_once("Zend/Log.php");
require_once("../../library/Icinga/Application/Logger.php");
require_once("../../library/Icinga/Protocol/Commandpipe/IComment.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Comment.php");
require_once("../../library/Icinga/Protocol/Commandpipe/CommandPipe.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Acknowledgement.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Downtime.php");
require_once("../../library/Icinga/Protocol/Commandpipe/PropertyModifier.php");
require_once("../../library/Icinga/Protocol/Commandpipe/Exception/InvalidCommandException.php");
if(!defined("EXTCMD_TEST_BIN")) if(!defined("EXTCMD_TEST_BIN"))
define("EXTCMD_TEST_BIN", "./bin/extcmd_test"); define("EXTCMD_TEST_BIN", "./bin/extcmd_test");
/**
* Several tests for the command pipe component
*
* Uses the helper script extcmd_test, which is basically the extracted command
* parser functions from the icinga core
*
*
*/
class CommandPipeTest extends \PHPUnit_Framework_TestCase class CommandPipeTest extends \PHPUnit_Framework_TestCase
{ {
/**
* Return the path of the test pipe used in these tests
*
* @return string
*/
public function getPipeName() public function getPipeName()
{ {
return sys_get_temp_dir()."/icinga_test_pipe"; return sys_get_temp_dir()."/icinga_test_pipe";
} }
private function getTestPipe()
/**
* Return a @see Icinga\Protocal\CommandPipe\CommandPipe instance set up for the local test pipe
*
* @return Commandpipe
*/
private function getLocalTestPipe()
{ {
$tmpPipe = $this->getPipeName(); $tmpPipe = $this->getPipeName();
$this->cleanup(); $this->cleanup();
@ -45,11 +55,54 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
return $pipe; return $pipe;
} }
/**
* Return a @see Icinga\Protocal\CommandPipe\CommandPipe instance set up for the local test pipe, but with ssh as the transport layer
*
* @return Commandpipe
*/
private function getSSHTestPipe()
{
$tmpPipe = $this->getPipeName();
$this->cleanup();
touch($tmpPipe);
$cfg = new \Zend_Config(array(
"path" => $tmpPipe,
"user" => "vagrant",
"password" => "vagrant",
"host" => 'localhost',
"port" => 22,
"name" => "test"
));
$comment = new Comment("Autor","Comment");
$pipe = new Commandpipe($cfg);
return $pipe;
}
/**
* Remove the testpipe if it exists
*
*/
private function cleanup() { private function cleanup() {
if(file_exists($this->getPipeName())) if(file_exists($this->getPipeName()))
unlink($this->getPipeName()); unlink($this->getPipeName());
} }
/**
* Query the extcmd_test script with $command or the command pipe and test whether the result is $exceptedString and
* has a return code of 0.
*
* Note:
* - if no string is given, only the return code is tested
* - if no command is given, the content of the test commandpipe is used
*
* This helps testing whether commandpipe serialization works correctly
*
* @param bool $expectedString The string that is expected to be returned from the extcmd_test binary
* (optional, leave it to just test for the return code)
* @param bool $command The commandstring to send (optional, leave it for using the command pipe content)
*/
private function assertCommandSucceeded($expectedString = false,$command = false) { private function assertCommandSucceeded($expectedString = false,$command = false) {
$resultCode = null; $resultCode = null;
$resultArr = array(); $resultArr = array();
@ -59,12 +112,19 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
return; return;
$this->assertEquals( $this->assertEquals(
$expectedString, $expectedString,
$receivedCmd $receivedCmd,
'Asserting that the command icinga received matches the command we send'
); );
} }
/**
* Test whether a single host acknowledgment is serialized and send correctly
*
* @throws \Exception|Exception
*/
public function testAcknowledgeSingleHost() public function testAcknowledgeSingleHost()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$ack = new Acknowledgement(new Comment("I can","sends teh ack")); $ack = new Acknowledgement(new Comment("I can","sends teh ack"));
$pipe->acknowledge(array( $pipe->acknowledge(array(
@ -80,12 +140,17 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether multiple host and service acknowledgments are serialized and send correctly
*
* @throws \Exception|Exception
*/
public function testAcknowledgeMultipleObjects() public function testAcknowledgeMultipleObjects()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$ack = new Comment("I can","sends teh ack"); $ack = new Comment("I can","sends teh ack");
$pipe->fopen_mode = "a"; $pipe->getTransport()->setOpenMode("a");
$pipe->acknowledge(array( $pipe->acknowledge(array(
(object) array( (object) array(
"host_name" => "hostA" "host_name" => "hostA"
@ -100,8 +165,7 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
),$ack); ),$ack);
$result = explode("\n",file_get_contents($this->getPipeName())); $result = explode("\n",file_get_contents($this->getPipeName()));
$this->assertCount(5, $result, "Asserting the correct number of commands being written to the command pipe");
$this->assertCount(5,$result);
$this->assertCommandSucceeded("ACKNOWLEDGE_HOST_PROBLEM;hostA;0;0;0;I can;sends teh ack",$result[0]); $this->assertCommandSucceeded("ACKNOWLEDGE_HOST_PROBLEM;hostA;0;0;0;I can;sends teh ack",$result[0]);
$this->assertCommandSucceeded("ACKNOWLEDGE_HOST_PROBLEM;hostB;0;0;0;I can;sends teh ack",$result[1]); $this->assertCommandSucceeded("ACKNOWLEDGE_HOST_PROBLEM;hostB;0;0;0;I can;sends teh ack",$result[1]);
@ -115,9 +179,14 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether a single host comment is correctly serialized and send to the command pipe
*
* @throws \Exception|Exception
*/
public function testAddHostComment() public function testAddHostComment()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$pipe->addComment(array((object) array("host_name" => "hostA")), $pipe->addComment(array((object) array("host_name" => "hostA")),
new Comment("Autor","Comment") new Comment("Autor","Comment")
@ -130,9 +199,14 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether removing all hostcomments is correctly serialized and send to the command pipe
*
* @throws \Exception|Exception
*/
public function testRemoveAllHostComment() public function testRemoveAllHostComment()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$pipe->removeComment(array( $pipe->removeComment(array(
(object) array( (object) array(
@ -147,9 +221,14 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether removing a single host comment is correctly serialized and send to the command pipe
*
* @throws \Exception|Exception
*/
public function testRemoveSpecificComment() public function testRemoveSpecificComment()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$pipe->removeComment(array((object) array("comment_id"=>34,"host_name"=>"test"))); $pipe->removeComment(array((object) array("comment_id"=>34,"host_name"=>"test")));
$this->assertCommandSucceeded("DEL_HOST_COMMENT;34"); $this->assertCommandSucceeded("DEL_HOST_COMMENT;34");
@ -160,11 +239,16 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether a multiple reschedules for services and hosts are correctly serialized and send to the commandpipe
*
* @throws \Exception|Exception
*/
public function testScheduleChecks() public function testScheduleChecks()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$pipe->fopen_mode = "a"; // append so we have multiple results $pipe->getTransport()->setOpenMode("a"); // append so we have multiple results
$t = time(); $t = time();
// normal reschedule // normal reschedule
$pipe->scheduleCheck(array( $pipe->scheduleCheck(array(
@ -182,7 +266,7 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
),$t,true); ),$t,true);
$result = explode("\n",file_get_contents($this->getPipeName())); $result = explode("\n",file_get_contents($this->getPipeName()));
$this->assertCount(6,$result); $this->assertCount(6,$result, "Asserting a correct number of commands being written to the commandpipe");
$this->assertCommandSucceeded("SCHEDULE_HOST_CHECK;test;".$t,$result[0]); $this->assertCommandSucceeded("SCHEDULE_HOST_CHECK;test;".$t,$result[0]);
$this->assertCommandSucceeded("SCHEDULE_SVC_CHECK;test;svc1;".$t,$result[1]); $this->assertCommandSucceeded("SCHEDULE_SVC_CHECK;test;svc1;".$t,$result[1]);
@ -198,11 +282,16 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether modifying monitoringflags of a host and service is correctly serialized and send to the command pipe
*
* @throws \Exception|Exception
*/
public function testObjectStateModifications() public function testObjectStateModifications()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$pipe->fopen_mode = "a"; $pipe->getTransport()->setOpenMode("a");
$pipe->setMonitoringProperties(array( $pipe->setMonitoringProperties(array(
(object) array( (object) array(
"host_name" => "Testhost" "host_name" => "Testhost"
@ -223,7 +312,7 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$result = explode("\n",file_get_contents($this->getPipeName())); $result = explode("\n",file_get_contents($this->getPipeName()));
array_pop($result); // remove empty last line array_pop($result); // remove empty last line
$this->assertCount(12,$result); $this->assertCount(12,$result, "Asserting a correct number of commands being written to the commandpipe");
foreach ($result as $command) { foreach ($result as $command) {
$this->assertCommandSucceeded(false,$command); $this->assertCommandSucceeded(false,$command);
} }
@ -235,9 +324,14 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether enabling and disabling global notifications are send correctly to the pipe
*
* @throws \Exception|Exception
*/
public function testGlobalNotificationTrigger() public function testGlobalNotificationTrigger()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$pipe->enableGlobalNotifications(); $pipe->enableGlobalNotifications();
$this->assertCommandSucceeded("ENABLE_NOTIFICATIONS;"); $this->assertCommandSucceeded("ENABLE_NOTIFICATIONS;");
@ -250,9 +344,14 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether host and servicedowntimes are correctly scheduled
*
* @throws \Exception|Exception
*/
public function testScheduleDowntime() public function testScheduleDowntime()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$downtime = new Downtime(25,26,new Comment("me","test")); $downtime = new Downtime(25,26,new Comment("me","test"));
$pipe->scheduleDowntime(array( $pipe->scheduleDowntime(array(
@ -260,7 +359,7 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
"host_name" => "Testhost" "host_name" => "Testhost"
) )
),$downtime); ),$downtime);
$this->assertCommandSucceeded("SCHEDULE_HOST_DOWNTIME;Testhost;25;26;0;0;0;me;test"); $this->assertCommandSucceeded("SCHEDULE_HOST_DOWNTIME;Testhost;25;26;1;0;0;me;test");
$pipe->scheduleDowntime(array( $pipe->scheduleDowntime(array(
(object) array( (object) array(
@ -268,7 +367,7 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
"service_description" => "svc" "service_description" => "svc"
) )
),$downtime); ),$downtime);
$this->assertCommandSucceeded("SCHEDULE_SVC_DOWNTIME;Testhost;svc;25;26;0;0;0;me;test"); $this->assertCommandSucceeded("SCHEDULE_SVC_DOWNTIME;Testhost;svc;25;26;1;0;0;me;test");
} catch (Exception $e) { } catch (Exception $e) {
$this->cleanup(); $this->cleanup();
@ -277,11 +376,16 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether the removal of downtimes is correctly serialized and send to the commandpipe for hosts and services
*
* @throws \Exception|Exception
*/
public function testRemoveDowntime() public function testRemoveDowntime()
{ {
$pipe = $this->getTestPipe(); $pipe = $this->getLocalTestPipe();
try { try {
$pipe->fopen_mode = "a"; $pipe->getTransport()->setOpenMode("a");
$pipe->removeDowntime(array( $pipe->removeDowntime(array(
(object) array( (object) array(
"host_name" => "Testhost" "host_name" => "Testhost"
@ -298,7 +402,7 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
)); ));
$result = explode("\n",file_get_contents($this->getPipeName())); $result = explode("\n",file_get_contents($this->getPipeName()));
array_pop($result); // remove empty last line array_pop($result); // remove empty last line
$this->assertCount(3,$result); $this->assertCount(3,$result, "Asserting a correct number of commands being written to the commandpipe");
$this->assertCommandSucceeded("DEL_DOWNTIME_BY_HOST_NAME;Testhost",$result[0]); $this->assertCommandSucceeded("DEL_DOWNTIME_BY_HOST_NAME;Testhost",$result[0]);
$this->assertCommandSucceeded("DEL_DOWNTIME_BY_HOST_NAME;host;svc",$result[1]); $this->assertCommandSucceeded("DEL_DOWNTIME_BY_HOST_NAME;host;svc",$result[1]);
$this->assertCommandSucceeded("DEL_SVC_DOWNTIME;123",$result[2]); $this->assertCommandSucceeded("DEL_SVC_DOWNTIME;123",$result[2]);
@ -310,4 +414,82 @@ class CommandPipeTest extends \PHPUnit_Framework_TestCase
$this->cleanup(); $this->cleanup();
} }
/**
* Test whether custom servicenotifications are correctly send to the commandpipe without options
*
* @throws \Exception
*/
public function testSendCustomServiceNotification()
{
$pipe = $this->getLocalTestPipe();
try {
$comment = new Comment("author", "commenttext");
$pipe->sendCustomNotification(array(
(object) array(
"host_name" => "host1",
"service_description" => "service1"
)
), $comment);
$this->assertCommandSucceeded(
"SEND_CUSTOM_SVC_NOTIFICATION;host1;service1;0;author;commenttext"
);
} catch (Exception $e) {
$this->cleanup();
throw $e;
}
$this->cleanup();
}
/**
* Test whether custom hostnotifications are correctly send to the commandpipe with a varlist of options
*
* @throws \Exception
*/
public function testSendCustomHostNotificationWithOptions()
{
$pipe = $this->getLocalTestPipe();
try {
$comment = new Comment('author', 'commenttext');
$pipe->sendCustomNotification(array(
(object) array(
'host_name' => 'host'
)
), $comment, Commandpipe::NOTIFY_FORCED, Commandpipe::NOTIFY_BROADCAST, Commandpipe::NOTIFY_INCREMENT);
$this->assertCommandSucceeded(
'SEND_CUSTOM_HOST_NOTIFICATION;host;7;author;commenttext'
);
} catch (Exception $e) {
$this->cleanup();
throw $e;
}
$this->cleanup();
}
/**
* Test sending of commands via SSH (currently disabled)
*
* @throws \Exception|Exception
*/
public function testSSHCommands()
{
$this->markTestSkipped("This test assumes running in a vagrant VM with key-auth");
if (!is_dir("/vagrant")) {
}
$pipe = $this->getSSHTestPipe();
try {
$ack = new Acknowledgement(new Comment("I can","sends teh ack"));
$pipe->acknowledge(array(
(object) array(
"host_name" => "hostA"
)
),$ack);
$this->assertCommandSucceeded("ACKNOWLEDGE_HOST_PROBLEM;hostA;0;0;0;I can;sends teh ack");
} catch(Exception $e) {
$this->cleanup();
throw $e;
}
$this->cleanup();
}
} }