1 <?php
defined('SYSPATH') OR die('No direct access allowed.');
5 * Requires authentication. See the helper nagioscmd for more info.
7 * op5, and the op5 logo are trademarks, servicemarks, registered servicemarks
8 * or registered trademarks of op5 AB.
9 * All other trademarks, servicemarks, registered trademarks, and registered
10 * servicemarks mentioned herein may be the property of their respective owner(s).
11 * The information contained herein is provided AS IS with NO WARRANTY OF ANY
12 * KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A
15 class Command_Controller
extends Authenticated_Controller
17 private $command_id = false;
18 private $cmd_params = array();
19 private $csrf_token = false;
21 * @var int = 300, if the starting time of a scheduled downtime is
22 * older than this many seconds, it's considered to have been added retrospectively
24 private $grace_time_in_s = 300;
27 * Initializes a page with the correct view, java-scripts and css
28 * @param $view The name of the page we want to print
30 protected function init_page($view)
32 $this->template
->content
= $this->add_view($view);
33 $this->template
->disable_refresh
= true;
37 * @param string $submitted_start_time (Y-m-d H:i:s)
38 * @param string $submitted_end_time (Y-m-d H:i:s)
39 * @return true | string (string = error message)
41 private function _validate_dates($submitted_start_time, $submitted_end_time) {
42 $start_time = nagstat
::timestamp_format(nagstat
::date_format(), $submitted_start_time);
43 $end_time = nagstat
::timestamp_format(nagstat
::date_format(), $submitted_end_time);
45 if(!$start_time ||
!$end_time) {
46 if(!$start_time && !$end_time) {
47 return "Neither of your submitted dates are valid, please <a href='javascript:history.back();'>adjust them</a>";
49 return sprintf("%s is not a valid date, please <a href='javascript:history.back();'>adjust it</a>", $start_time ?
$submitted_end_time : $submitted_start_time);
52 if($start_time > $end_time) {
53 return sprintf("The downtime can not end before it starts. Please <a href='javascript:history.back();'>adjust it</a>", $submitted_start_time);
59 * Create a standard checkbox item
60 * @param $description The user visible text for this option
61 * @param $name The internal name for this option
62 * @return array suitable for passing to the request template
64 protected function cb($description, $name)
66 $value = Execute_Command_Model
::get_setting($name);
67 return array('type' => 'checkbox', 'name' => $description, 'default' => $value);
71 * Request a command to be submitted
72 * This method prints input fields to be selected for the
74 * @param $name The requested command to run
75 * @param $parameters The parameters (host_name etc) for the command
77 public function submit($cmd = false, $params=false)
79 $this->init_page('command/request');
80 $this->xtra_js
[] = $this->add_path('command/js/command.js');
83 $cmd = $this->input
->get('cmd_typ');
86 if ($params === false) {
90 if (($auth_check = nagioscmd
::is_authorized_for($params)) !== true)
91 return $this->unauthorized($auth_check);
93 $this->template
->content
->cmd_typ
= $cmd;
95 $command = new Execute_Command_Model
;
96 $info = $command->get_command_info($cmd, $params);
97 $param = $info['params'];
99 case 'DEL_HOST_COMMENT':
100 case 'DEL_SVC_COMMENT':
101 $param['comment_id']['type'] = 'immutable';
103 case 'SCHEDULE_HOST_CHECK':
104 case 'SCHEDULE_SVC_CHECK':
105 case 'SCHEDULE_HOST_SVC_CHECKS':
106 $param['_force'] = $this->cb(_('Force Check'), '_force');
109 case 'PROCESS_HOST_CHECK_RESULT':
110 case 'PROCESS_SERVICE_CHECK_RESULT':
111 $param['_perfdata'] = array
114 'name' => _('Performance data'));
117 case 'SCHEDULE_HOST_DOWNTIME':
118 $this->template
->inline_js
= "grace_time_in_s = '$this->grace_time_in_s'";
119 $this->xtra_js
[] = $this->add_path('command/js/schedule_downtime.js');
120 $param['_child-hosts'] = array
123 ('none' => _('Do nothing'),
124 'triggered' => _('Schedule triggered downtime'),
125 'fixed' => _('Schedule fixed downtime')),
126 'default' => 'triggered',
127 'name' => _('Child Hosts'));
129 case 'SCHEDULE_HOSTGROUP_HOST_DOWNTIME':
131 case 'SCHEDULE_SVC_DOWNTIME':
132 $this->template
->inline_js
= "grace_time_in_s = '$this->grace_time_in_s'";
133 $this->xtra_js
[] = $this->add_path('command/js/schedule_downtime.js');
136 case 'SEND_CUSTOM_SVC_NOTIFICATION':
137 case 'SEND_CUSTOM_HOST_NOTIFICATION':
138 $param['_broadcast'] = $this->cb(_('Broadcast'), '_broadcast');
139 $param['_force'] = $this->cb(_('Force notification'), '_force');
140 $param['_increment'] = $this->cb(_('Increment notification number'), '_increment');
143 case 'ENABLE_HOST_SVC_CHECKS':
144 case 'DISABLE_HOST_SVC_CHECKS':
145 case 'ENABLE_HOSTGROUP_SVC_CHECKS':
146 case 'DISABLE_HOSTGROUP_SVC_CHECKS':
147 case 'ENABLE_SERVICEGROUP_SVC_CHECKS':
148 case 'DISABLE_SERVICEGROUP_SVC_CHECKS':
149 $en_dis = $cmd{0} === 'E' ?
_('Enable') : _('Disable');
150 $param['_host-too'] = $this->cb(sprintf(_('%s checks for host too'), $en_dis), '_host-too');
153 case 'ENABLE_HOST_CHECK':
154 case 'DISABLE_HOST_CHECK':
155 $en_dis = $cmd{0} === 'E' ?
_('Enable') : _('Disable');
156 $param['_services-too'] = $this->cb(sprintf(_('%s checks for services too'), $en_dis), '_services-too');
159 case 'ENABLE_HOST_SVC_NOTIFICATIONS':
160 case 'DISABLE_HOST_SVC_NOTIFICATIONS':
161 $en_dis = $cmd{0} === 'E' ?
_('Enable') : _('Disable');
162 $param['_host-too'] = $this->cb(sprintf(_('%s notifications for host too'), $en_dis), '_host-too');
165 case 'ACKNOWLEDGE_HOST_PROBLEM':
166 $param['_services-too'] = $this->cb(_('Acknowledge any problems on services too'), '_services-too');
168 case 'REMOVE_HOST_ACKNOWLEDGEMENT':
169 $param['_services-too'] = $this->cb(_('Remove any acknowledgements on services too'), '_services-too');
171 case 'NACOMA_DEL_SERVICE':
173 foreach ($params['service'] as $service) {
174 if (($hg = nacoma
::getHostgroupForService($service)))
175 $res[$service] = $hg;
179 $info['brief'] = ngettext(
180 "You've selected a service that is saved on a hostgroup",
181 "You've selected services that are saved on hostgroups", count($res));;
182 $info['description'] = '<ul>';
183 foreach ($res as $svc => $hg) {
184 $info['description'] .= sprintf(_('<li>%s is saved on %s</li>'), $svc, $hg);
186 $info['description'] .= '</ul><p>'.ngettext(
187 'Deleting it will delete it from all hosts in the hostgroup. Are you sure? You might instead want to create a better service directly on the host.',
188 'Deleting them will delete them from all the hosts in the hostgroup. Are you sure? You might instead want to create better services directly on the affected hosts.', count($res)).'</p>';
191 case 'NACOMA_DEL_HOST':
192 return $this->commit($cmd, $params);
197 $info['params'] = $param;
199 $this->template
->content
->info
= $info;
203 protected function schedule_retrospectively($selector_type, $target_type, $obj_names, $start_time, $end_time, $comment)
205 $start_time = nagstat
::timestamp_format(nagstat
::date_format(), $start_time);
206 $end_time = nagstat
::timestamp_format(nagstat
::date_format(), $end_time);
209 if ($start_time +
$this->grace_time_in_s
>= $now)
212 if (!is_array($obj_names))
213 $obj_names = array($obj_names);
215 // Some Assembly Required
216 if ($selector_type != $target_type) {
217 $ls = Livestatus
::instance();
218 $individual_objs = array();
219 if ($target_type === 'service' && $selector_type === 'servicegroup') {
220 foreach ($obj_names as $gname) {
221 foreach ($ls->getServices(array('filter' => array('groups' => array('>=' => $gname)), 'columns' => array('host_name', 'description'))) as $row) {
222 $individual_objs[] = $row['host_name'].';'.$row['description'];
226 else if ($target_type === 'service' && $selector_type === 'hostgroup') {
227 foreach ($obj_names as $gname) {
228 foreach ($ls->getServices(array('filter' => array('host_groups' => array('>=' => $gname)), 'columns' => array('host_name', 'description'))) as $row) {
229 $individual_objs[] = $row['host_name'].';'.$row['description'];
233 else if ($target_type === 'host' && $selector_type === 'hostgroup') {
234 foreach ($obj_names as $gname) {
235 foreach ($ls->getHosts(array('filter' => array('groups' => array('>=' => $gname)), 'columns' => array('name'))) as $row) {
236 $individual_objs[$row['name']] = 1;
239 $individual_objs = array_keys($individual_objs);
241 else if ($target_type === 'host' && $selector_type === 'servicegroup') {
242 foreach ($obj_names as $gname) {
243 foreach ($ls->getServices(array('filter' => array('groups' => array('>=' => $gname)), 'columns' => array('host_name'))) as $row) {
244 $individual_objs[$row['host_name']] = 1;
247 $individual_objs = array_keys($individual_objs);
249 else if ($target_type === 'service' && $selector_type === 'host') {
250 foreach ($obj_names as $hname) {
251 foreach ($ls->getServices(array('filter' => array('host_name' => $hname), 'columns' => array('host_name', 'description'))) as $row) {
252 $individual_objs[] = $row['host_name'].';'.$row['description'];
256 $obj_names = $individual_objs;
259 $db = Database
::instance();
260 foreach ($obj_names as $obj_name) {
261 if ($target_type == 'service') {
262 list($host_name, $service_desc) = explode(';', $obj_name);
263 $host_name = $db->escape($host_name);
264 $service_desc = $db->escape($service_desc);
267 $host_name = $db->escape($obj_name);
268 $service_desc = "''";
270 $start_msg = $db->escape(ucfirst($selector_type)." has entered a period of retroactively added scheduled downtime, reported by '".Auth
::instance()->get_user()->username
."', reason: '".$comment."'");
271 $end_msg = $db->escape(ucfirst($selector_type)." has exited a period of retroactively added scheduled downtime, reported by '".Auth
::instance()->get_user()->username
."', reason: '".$comment."'");
273 $db->query("INSERT INTO report_data(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($start_time, 1103, $host_name, $service_desc, 1, $start_msg)");
274 $db->query("INSERT INTO report_data_extras(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($start_time, 1103, $host_name, $service_desc, 1, $start_msg)");
275 $db->query("INSERT INTO report_data(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($end_time, 1104, $host_name, $service_desc, 0, $end_msg)");
276 $db->query("INSERT INTO report_data_extras(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($end_time, 1104, $host_name, $service_desc, 0, $end_msg)");
281 * Takes the command parameters given by the "submit" function
282 * and creates a Nagios command that gets fed to Nagios through
285 public function commit($cmd = false, $param=false)
288 if(!isset($_REQUEST['cmd_typ']))
289 return $this->unauthorized();
290 $cmd = $_REQUEST['cmd_typ'];
294 $param = isset($_REQUEST['cmd_param']) ?
$_REQUEST['cmd_param'] : array();
296 $this->init_page('command/commit');
297 $this->template
->content
->cmd_typ
= $cmd;
299 $nagios_commands = array();
300 if (($auth_check = nagioscmd
::is_authorized_for($param, $cmd)) !== true)
301 return $this->unauthorized($auth_check);
303 $param['author'] = Auth
::instance()->get_user()->username
;
305 if (isset($param['comment']) && trim($param['comment'])=='') {
306 # comments shouldn't ever be empty
307 $this->template
->content
->result
= false;
308 $this->template
->content
->error
= _("Required field 'Comment' was not entered").'<br />'.
309 _(sprintf('Go %s back %s and verify that you entered all required information correctly', '<a href="javascript:history.back();">', '</a>'));
312 $fallthrough = false;
314 case 'SCHEDULE_HOST_CHECK':
315 case 'SCHEDULE_SVC_CHECK':
316 case 'SCHEDULE_HOST_SVC_CHECKS':
317 if (!empty($param['_force'])) {
318 unset($param['force']);
319 $cmd = 'SCHEDULE_FORCED' . substr($cmd, strlen("SCHEDULE"));
323 case 'PROCESS_HOST_CHECK_RESULT':
324 case 'PROCESS_SERVICE_CHECK_RESULT':
325 if (!empty($param['_perfdata']) && !empty($param['plugin_output'])) {
326 $param['plugin_output'] .= "|".$param['_perfdata'];
327 unset($param['perfdata']);
331 case 'SCHEDULE_HOST_DOWNTIME':
332 $date_validation_result = $this->_validate_dates($param['start_time'], $param['end_time']);
333 if($date_validation_result !== true) {
334 $this->template
->content
->result
= false;
335 $this->template
->content
->error
= $date_validation_result;
338 if (!empty($param['_child-hosts']) && $param['_child-hosts'] != 'none') {
339 $what = $param['_child-hosts'];
340 unset($param['_child-hosts']);
341 if ($what === 'triggered') {
342 $cmd = 'SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME';
343 } elseif ($what === 'fixed') {
344 $cmd = 'SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME';
347 if(isset($param['fixed']) && $param['fixed']) {
348 $this->schedule_retrospectively('host', 'host', $param['host_name'], $param['start_time'], $param['end_time'], $param['comment']);
351 # fallthrough to services-too handling
352 case 'SCHEDULE_HOSTGROUP_HOST_DOWNTIME':
353 if(!$fallthrough && isset($param['fixed']) && $param['fixed']) {
354 $this->schedule_retrospectively('hostgroup', 'host', $param['hostgroup_name'], $param['start_time'], $param['end_time'], $param['comment']);
356 if (!empty($param['_services-too'])) {
357 unset($param['_services-too']);
359 $nagios_commands = array_merge($this->_build_command('SCHEDULE_HOST_SVC_DOWNTIME', $param), $nagios_commands);
361 $nagios_commands = array_merge($this->_build_command('SCHEDULE_HOSTGROUP_SVC_DOWNTIME', $param), $nagios_commands);
363 if(isset($param['fixed']) && $param['fixed']) {
364 $grouptype = $fallthrough?
'host':'hostgroup';
365 $this->schedule_retrospectively($grouptype, 'service', $param[$grouptype.'_name'], $param['start_time'], $param['end_time'], $param['comment']);
370 case 'SEND_CUSTOM_HOST_NOTIFICATION':
371 case 'SEND_CUSTOM_SVC_NOTIFICATION':
373 if (isset($param['_broadcast'])) {
374 unset($param['_broadcast']);
377 if (isset($param['_force'])) {
378 unset($param['_force']);
381 if (isset($param['_increment'])) {
382 unset($param['_increment']);
386 $param['options'] = $options;
389 case 'ENABLE_HOST_SVC_CHECKS':
390 case 'DISABLE_HOST_SVC_CHECKS':
391 $xcmd = $cmd{0} === 'D' ?
'DISABLE' : 'ENABLE';
392 $xcmd .= '_HOST_CHECK';
393 if (!empty($param['_host-too']))
394 $nagios_commands = $this->_build_command($xcmd, $param);
397 case 'ENABLE_HOST_CHECK':
398 case 'DISABLE_HOST_CHECK':
399 $xcmd = $cmd{0} === 'D' ?
'DISABLE' : 'ENABLE';
400 $xcmd .= '_HOST_SVC_CHECKS';
401 if (!empty($param['_services-too']))
402 $nagios_commands = $this->_build_command($xcmd, $param);
405 case 'ENABLE_HOST_SVC_NOTIFICATIONS':
406 case 'DISABLE_HOST_SVC_NOTIFICATIONS':
407 $xcmd = $cmd{0} === 'D' ?
'DISABLE' : 'ENABLE';
408 $xcmd .= '_HOST_NOTIFICATIONS';
409 if (!empty($param['_host-too']))
410 $nagios_commands = $this->_build_command($xcmd, $param);
412 case 'ENABLE_HOSTGROUP_SVC_CHECKS':
413 case 'DISABLE_HOSTGROUP_SVC_CHECKS':
414 case 'ENABLE_SERVICEGROUP_SVC_CHECKS':
415 case 'DISABLE_SERVICEGROUP_SVC_CHECKS':
416 case 'ENABLE_HOSTGROUP_SVC_NOTIFICATIONS':
417 case 'DISABLE_HOSTGROUP_SVC_NOTIFICATIONS':
418 case 'ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS':
419 case 'DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS':
420 case 'SCHEDULE_HOSTGROUP_SVC_DOWNTIME':
421 case 'SCHEDULE_SERVICEGROUP_SVC_DOWNTIME':
422 if(strpos($cmd, 'DOWNTIME') && isset($param['fixed']) && $param['fixed']) {
423 $grouptype = strtolower(substr($cmd, 9, strpos($cmd, '_', 10) - 9));
424 $this->schedule_retrospectively($grouptype, 'service', $param[$grouptype.'_name'], $param['start_time'], $param['end_time'], $param['comment']);
425 if (!empty($param['_host-too']))
426 $this->schedule_retrospectively($grouptype, 'host', $param[$grouptype.'_name'], $param['start_time'], $param['end_time'], $param['comment']);
428 if (!empty($param['_host-too'])) {
429 unset($param['_host-too']);
430 $xcmd = str_replace('SVC', 'HOST', $cmd);
431 $nagios_commands = $this->_build_command($xcmd, $param);
434 case 'SCHEDULE_SVC_DOWNTIME':
435 if(isset($param['fixed']) && $param['fixed']) {
436 $this->schedule_retrospectively('service', 'service', $param['service'], $param['start_time'], $param['end_time'], $param['comment']);
438 $date_validation_result = $this->_validate_dates($param['start_time'], $param['end_time']);
439 if($date_validation_result !== true) {
440 $this->template
->content
->result
= false;
441 $this->template
->content
->error
= $date_validation_result;
445 case 'ACKNOWLEDGE_HOST_PROBLEM':
446 case 'REMOVE_HOST_ACKNOWLEDGEMENT':
447 if (!empty($param['_services-too'])) {
448 unset($param['_services-too']);
449 $xcmd = str_replace('HOST', 'SVC', $cmd);
450 $ls = Livestatus
::instance();
451 $host_names = $param['host_name'];
452 if (!is_array($host_names))
453 $host_names = array($host_names);
455 unset($xparam['host_name']);
456 foreach ($host_names as $host_name) {
457 $services = $ls->getServices(array('filter' => array('host_name' => $host_name), 'columns' => array('description')));
459 foreach($services as $service) {
460 $xparam['service'] = $host_name.';'.$service['description'];
461 $nagios_commands = $this->_build_command($xcmd, $xparam, $nagios_commands);
467 case 'SCHEDULE_SERVICEGROUP_HOST_DOWNTIME':
468 if(isset($param['fixed']) && $param['fixed']) {
469 $this->schedule_retrospectively('servicegroup', 'host', $param['servicegroup_name'], $param['start_time'], $param['end_time'], $param['comment']);
472 case 'NACOMA_DEL_HOST':
473 case 'NACOMA_DEL_SERVICE':
474 // Delete the host/service then route to NACOMA SAVE_CONFIG page
476 if (isset($param['service'])) {
477 foreach ($param['service'] as $service) {
478 $res &= nacoma
::delService($service);
482 if (isset($param['host_name'])) {
483 foreach ($param['host_name'] as $host) {
484 $res &= nacoma
::delHost($host);
489 return url
::redirect('/configuration/configure?page=export.php');
493 $nagios_commands = $this->_build_command($cmd, $param, $nagios_commands);
495 if (empty($nagios_commands))
496 $this->template
->content
->result
= false;
498 $this->template
->content
->result
= true;
499 while ($ncmd = array_pop($nagios_commands)) {
500 //Clarification: not submitting any more commands if a
501 //previous one failed (indicated by && which
502 //never continues if result is false
503 $this->template
->content
->result
= $this->template
->content
->result
&& nagioscmd
::submit_to_nagios($ncmd);
508 * Display "You're not authorized" message
510 public function unauthorized($state=false)
512 $this->template
->content
= $this->add_view('command/unauthorized');
513 $this->template
->content
->error_message
= _('You are not authorized to submit the specified command.');
515 case -1: # No command passed
516 $this->template
->content
->error_message
= _('No command specified.');
517 $this->template
->content
->error_description
= _('Please enter a valid '.
518 'command or use the available links in the GUI.');
520 case -2: # Contact can't submit commands
521 $this->template
->content
->error_description
= _("Your contact doesn't seem to configured ".
522 "to allow you to submit commands (i.e 'can_submit_commands' is not enabled). Please contact an administrator ".
523 "to enable this for you. ");
525 case -3: # not authorized from cgi.cfg, and not a configured contact
526 $this->template
->content
->error_description
= _("Your account doesn't have a " .
527 "configured contact, nor does it have permissions to submit commands to all " .
528 "objects. Please contact an administrator for assistance.");
531 $this->template
->content
->error_description
= _("Your account isn't authorized " .
532 "to submit commands for this object type. Please contact an administrator for assistance.");
535 $this->template
->content
->error_description
= _("Your account isn't authorized " .
536 "to submit commands for this object. Please contact an administrator for assistance.");
539 default: # fallthrough, not authorized for anything
540 $this->template
->content
->error_description
= _('Read the section of the '.
541 'documentation that deals with authentication and authorization in the CGIs for more information.');
544 $this->template
->content
->return_link_lable
= _('Return from where you came');
548 * Translated helptexts for this controller
550 public static function _helptexts($id)
552 # No helptexts defined yet - this is just an example
553 # Tag unfinished helptexts with @@@HELPTEXT:<key> to make it
554 # easier to find those later
557 _ ("The downtime you want to delete/cancel"),
559 _ ("With triggered downtime the start of the downtime ".
560 "is triggered by the start of some other scheduled " .
561 "host or service downtime"),
563 _("Duration is given as a decimal value of full hours. " .
564 "Thus, 1h 15m should be written as <b>1.25</b>"),
566 if (array_key_exists($id, $helptexts)) {
567 echo $helptexts[$id];
570 echo sprintf(_("This helptext ('%s') is not translated yet"), $id);
574 * Handle submitting of one command for multiple objects
576 public function multi_action()
578 if (!isset($_REQUEST['multi_action'])) {
579 $this->template
->content
= $this->add_view('error');
580 $this->template
->content
->error_message
= '<br /> '._('ERROR: Missing action parameter - unable to process request');
583 if (!isset($_REQUEST['object_select'])) {
584 $this->template
->content
= $this->add_view('error');
585 $this->template
->content
->error_message
= '<br /> '._('ERROR: Missing objects - unable to process request');
588 if (!isset($_REQUEST['obj_type'])) {
589 $this->template
->content
= $this->add_view('error');
590 $this->template
->content
->error_message
= '<br /> '._('ERROR: Missing object type - unable to process request');
594 $cmd_typ = $_REQUEST['multi_action'];
595 $obj_type = $_REQUEST['obj_type'];
596 $objects = $_REQUEST['object_select'];
601 $param_name = 'host_name';
604 $param_name = 'service';
607 $param_name = 'hostgroup_name';
609 case 'servicegroups':
610 $param_name = 'servicegroup_name';
613 $param_name = 'comment_id';
616 $param_name = 'downtime_id';
622 foreach ($objects as $obj) {
623 $params[$param_name][] = $obj;
626 if (!empty($params) && !empty($cmd_typ)) {
627 $params['cmd_typ'] = $cmd_typ;
628 return $this->submit($cmd_typ, $params);
631 $this->template
->content
= $this->add_view('error');
632 $this->template
->content
->error_message
= '<br /> '._('ERROR: Missing parameters - unable to process request');
637 * Wrapper around nagioscmd::build_command() to be able
638 * to create valid commands for multiple objects at once
640 public function _build_command($cmd = false, $param = false, $nagios_commands = false)
643 (isset($param['host_name']) && is_array($param['host_name'])) ||
644 (isset($param['service']) && is_array($param['service'])) )
645 { # we have a multi command, i.e one command for multiple objects
647 # remove host_name (or service) from param
648 if (isset($param['host_name'])) {
649 $obj_list = $param['host_name'];
650 unset($param['host_name']);
651 $param_str = 'host_name';
653 $obj_list = $param['service'];
654 unset($param['service']);
655 $param_str = 'service';
658 # create new param array for each object
659 foreach ($obj_list as $obj) {
660 $multi_param = false;
661 $multi_param = $param;
662 $multi_param[$param_str] = $obj;
663 $nagios_commands[] = nagioscmd
::build_command($cmd, $multi_param);
665 } else if ((isset($param['downtime_id']) && is_array($param['downtime_id'])) ||
666 (isset($param['trigger_id']) && is_array($param['trigger_id'])) ||
667 (isset($param['comment_id']) && is_array($param['comment_id']))) {
668 if (isset($param['trigger_id']))
669 $param_str = 'trigger_id';
670 elseif (isset($param['downtime_id']))
671 $param_str = 'downtime_id';
673 $param_str = 'comment_id';
674 foreach ($param[$param_str] as $did) {
675 $parts = explode(';',$did,2);
676 $replace_to_service = false;
677 if( count($parts) == 2 ) {
679 $replace_to_service = $parts[1] != 0;
681 $multi_param = $param;
682 $multi_param[$param_str] = $did;
684 $this_cmd = nagioscmd
::cmd_info($cmd); /* Needs to be extraced so _HOST_ can be replaced to _SVC_ */
685 if( $replace_to_service )
686 $this_cmd['template'] = str_replace('_HOST_','_SVC_',$this_cmd['template']);
687 $nagios_commands[] = nagioscmd
::build_command($this_cmd, $multi_param);
690 $nagios_commands[] = nagioscmd
::build_command($cmd, $param);
693 return $nagios_commands;
697 * Executes custom commands and return output to ajax call.
698 * @param $command_name string
699 * @param $type string
700 * @param $host string
701 * @param $service string
704 public function exec_custom_command($command_name, $type=false, $host=false, $service=false)
707 $this->auto_render
=false;
708 if ($host === false) {
709 echo "No object type or identifier were set. Aborting.";
713 $ls = Livestatus
::instance();
714 if(!empty($host) && empty($service)) {
715 $result_data = $ls->getHosts(array('filter' => array('name' => $host)));
717 else if(!empty($host) && !empty($service)) {
718 $result_data = $ls->getServices(array('filter' => array('host_name' => $host, 'description' => $service)));
720 $obj = (object)$result_data[0];
722 $custom_variables = array_combine($obj->custom_variable_names
, $obj->custom_variable_values
);
723 $custom_commands = Custom_command_Model
::parse_custom_variables($custom_variables, $command_name);
724 if (empty($custom_commands)) {
725 echo "You are not authorized to run this command or it doesn't exist.";
728 $command = $custom_commands[$command_name];
729 $command = nagstat
::process_macros($command, $obj, $type);
730 // Set host/service comment that the command has been run
733 $comment = "ADD_HOST_COMMENT;".$host.";1;".Auth
::instance()->get_user()->username
.";Executed custom command: ".ucwords(strtolower(str_replace('_', ' ', $command_name)));
736 $comment = "ADD_SVC_COMMENT;".$host.";".$service.";1;".Auth
::instance()->get_user()->username
.";Executed custom command: ".ucwords(strtolower(str_replace('_', ' ', $command_name)));
739 // Submit logs to nagios as comments.
740 $nagios_base_path = Kohana
::config('config.nagios_base_path');
741 nagioscmd
::submit_to_nagios($comment);
742 exec($command, $output, $status);
745 if (is_array($output)) {
746 $output = implode('<br />', $output);
750 echo "Script failed with status: " . $status;