parent
fb421d3756
commit
2615446572
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use Icinga\Module\Director\Web\Controller\ObjectsController;
|
||||
|
||||
class ScheduledDowntimesController extends ObjectsController
|
||||
{
|
||||
}
|
|
@ -457,6 +457,7 @@ class Db extends DbConnection
|
|||
'usergroup',
|
||||
'command',
|
||||
'timeperiod',
|
||||
'scheduled_downtime',
|
||||
'notification',
|
||||
'apiuser',
|
||||
'endpoint',
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Objects;
|
||||
|
||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||
|
||||
class IcingaScheduledDowntime extends IcingaObject
|
||||
{
|
||||
protected $table = 'icinga_scheduled_downtime';
|
||||
|
||||
protected $defaultProperties = array(
|
||||
'id' => null,
|
||||
'zone_id' => null,
|
||||
'object_name' => null,
|
||||
'object_type' => null,
|
||||
'disabled' => 'n',
|
||||
'display_name' => null,
|
||||
'author' => null,
|
||||
'comment' => null,
|
||||
'fixed' => null,
|
||||
'duration' => null,
|
||||
);
|
||||
|
||||
protected $supportsImports = true;
|
||||
|
||||
protected $supportsRanges = true;
|
||||
|
||||
protected $relations = array(
|
||||
'zone' => 'IcingaZone',
|
||||
);
|
||||
|
||||
protected $booleans = array(
|
||||
'fixed' => 'fixed',
|
||||
);
|
||||
|
||||
protected $intervalProperties = array(
|
||||
'duration' => 'duration',
|
||||
);
|
||||
|
||||
/**
|
||||
* Render update property
|
||||
*
|
||||
* Avoid complaints for method names with underscore:
|
||||
* @codingStandardsIgnoreStart
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderUpdate_method()
|
||||
{
|
||||
// @codingStandardsIgnoreEnd
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function renderObjectHeader()
|
||||
{
|
||||
return parent::renderObjectHeader()
|
||||
. ' import "legacy-timeperiod"' . "\n";
|
||||
}
|
||||
|
||||
public function isActive($now = null)
|
||||
{
|
||||
if ($now === null) {
|
||||
$now = time();
|
||||
}
|
||||
|
||||
foreach ($this->ranges()->getRanges() as $range) {
|
||||
if ($range->isActive($now)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: no range currently means (and renders) "never", Icinga behaves
|
||||
// different. Figure out whether and how we should support this
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function prefersGlobalZone()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Objects;
|
||||
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
|
||||
class IcingaScheduledDowntimeRange extends DbObject
|
||||
{
|
||||
protected $keyName = array('scheduled_downtime_id', 'range_key', 'range_type');
|
||||
|
||||
protected $table = 'icinga_scheduled_downtime_range';
|
||||
|
||||
protected $defaultProperties = array(
|
||||
'timeperiod_id' => null,
|
||||
'range_key' => null,
|
||||
'range_value' => null,
|
||||
'range_type' => 'include',
|
||||
'merge_behaviour' => 'set',
|
||||
);
|
||||
|
||||
public function isActive($now = null)
|
||||
{
|
||||
if ($now === null) {
|
||||
$now = time();
|
||||
}
|
||||
|
||||
if (false === ($wday = $this->getWeekDay($this->range_key))) {
|
||||
// TODO, dates are not yet supported
|
||||
return false;
|
||||
}
|
||||
|
||||
$wdayName = $this->range_key;
|
||||
|
||||
if ((int) strftime('%w', $now) !== $wday) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$timeRanges = preg_split('/\s*,\s*/', $this->range_value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
foreach ($timeRanges as $timeRange) {
|
||||
if ($this->timeRangeIsActive($timeRange, $now)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function timeRangeIsActive($rangeString, $now)
|
||||
{
|
||||
if (sscanf($rangeString, '%2d:%2d-%2d:%2d', $hBegin, $mBegin, $hEnd, $mEnd) === 4) {
|
||||
if ($this->timeFromHourMin($hBegin, $mBegin, $now) <= $now
|
||||
&& $this->timeFromHourMin($hEnd, $mEnd, $now) >= $now
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// TODO: throw exception?
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function timeFromHourMin($hour, $min, $now)
|
||||
{
|
||||
return strtotime(sprintf('%s %02d:%02d:00', date('Y-m-d', $now), $hour, $min));
|
||||
}
|
||||
|
||||
protected function getWeekDay($day)
|
||||
{
|
||||
switch ($day) {
|
||||
case 'sunday':
|
||||
return 0;
|
||||
case 'monday':
|
||||
return 1;
|
||||
case 'tuesday':
|
||||
return 2;
|
||||
case 'wednesday':
|
||||
return 3;
|
||||
case 'thursday':
|
||||
return 4;
|
||||
case 'friday':
|
||||
return 5;
|
||||
case 'saturday':
|
||||
return 6;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Objects;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Iterator;
|
||||
use Countable;
|
||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||
|
||||
class IcingaScheduledDowntimeRanges implements Iterator, Countable, IcingaConfigRenderer
|
||||
{
|
||||
protected $storedRanges = array();
|
||||
|
||||
protected $ranges = array();
|
||||
|
||||
protected $modified = false;
|
||||
|
||||
protected $object;
|
||||
|
||||
private $position = 0;
|
||||
|
||||
protected $idx = array();
|
||||
|
||||
public function __construct(IcingaObject $object)
|
||||
{
|
||||
$this->object = $object;
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->ranges);
|
||||
}
|
||||
|
||||
public function rewind()
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
public function hasBeenModified()
|
||||
{
|
||||
return $this->modified;
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
if (! $this->valid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->ranges[$this->idx[$this->position]];
|
||||
}
|
||||
|
||||
public function key()
|
||||
{
|
||||
return $this->idx[$this->position];
|
||||
}
|
||||
|
||||
public function next()
|
||||
{
|
||||
++$this->position;
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return array_key_exists($this->position, $this->idx);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
if (array_key_exists($key, $this->ranges)) {
|
||||
return $this->ranges[$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getValues()
|
||||
{
|
||||
$res = array();
|
||||
foreach ($this->ranges as $key => $range) {
|
||||
$res[$key] = $range->range_value;
|
||||
}
|
||||
|
||||
return (object) $res;
|
||||
}
|
||||
|
||||
public function getOriginalValues()
|
||||
{
|
||||
$res = array();
|
||||
foreach ($this->storedRanges as $key => $range) {
|
||||
$res[$key] = $range->range_value;
|
||||
}
|
||||
|
||||
return (object) $res;
|
||||
}
|
||||
|
||||
public function getRanges()
|
||||
{
|
||||
return $this->ranges;
|
||||
}
|
||||
|
||||
protected function modify($range, $value)
|
||||
{
|
||||
$this->ranges[$range]->range_key = $value;
|
||||
}
|
||||
|
||||
public function set($ranges)
|
||||
{
|
||||
foreach ($ranges as $range => $value) {
|
||||
$this->setRange($range, $value);
|
||||
}
|
||||
|
||||
$toDelete = array_diff(array_keys($this->ranges), array_keys($ranges));
|
||||
foreach ($toDelete as $range) {
|
||||
$this->remove($range);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRange($range, $value)
|
||||
{
|
||||
if ($value === null && array_key_exists($range, $this->ranges)) {
|
||||
$this->remove($range);
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (array_key_exists($range, $this->ranges)) {
|
||||
if ($this->ranges[$range]->range_value === $value) {
|
||||
return $this;
|
||||
} else {
|
||||
$this->ranges[$range]->range_value = $value;
|
||||
$this->modified = true;
|
||||
}
|
||||
} else {
|
||||
$this->ranges[$range] = IcingaTimePeriodRange::create(array(
|
||||
'timeperiod_id' => $this->object->id,
|
||||
'range_key' => $range,
|
||||
'range_value' => $value,
|
||||
));
|
||||
$this->modified = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic isset check
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset($range)
|
||||
{
|
||||
return array_key_exists($range, $this->ranges);
|
||||
}
|
||||
|
||||
public function remove($range)
|
||||
{
|
||||
if (array_key_exists($range, $this->ranges)) {
|
||||
unset($this->ranges[$range]);
|
||||
}
|
||||
|
||||
$this->modified = true;
|
||||
$this->refreshIndex();
|
||||
}
|
||||
|
||||
public function clear()
|
||||
{
|
||||
$this->ranges = array();
|
||||
$this->modified = true;
|
||||
$this->refreshIndex();
|
||||
}
|
||||
|
||||
protected function refreshIndex()
|
||||
{
|
||||
ksort($this->ranges);
|
||||
$this->idx = array_keys($this->ranges);
|
||||
}
|
||||
|
||||
protected function getRangeClass()
|
||||
{
|
||||
return __NAMESPACE__ . '\\Icinga' .ucfirst($this->object->getShortTableName()) . 'Range';
|
||||
}
|
||||
|
||||
public function listRangesNames()
|
||||
{
|
||||
return array_keys($this->ranges);
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->object->getShortTableName();
|
||||
}
|
||||
|
||||
public function getRangeTableName()
|
||||
{
|
||||
return $this->object->getTableName() . '_range';
|
||||
}
|
||||
|
||||
protected function loadFromDb()
|
||||
{
|
||||
$db = $this->object->getDb();
|
||||
$connection = $this->object->getConnection();
|
||||
|
||||
$table = $this->getRangeTableName();
|
||||
|
||||
$query = $db->select()->from(
|
||||
array('o' => $table)
|
||||
)->where('o.timeperiod_id = ?', (int) $this->object->id)
|
||||
->order('o.range_key');
|
||||
|
||||
$class = $this->getClass();
|
||||
$this->ranges = $class::loadAll($connection, $query, 'range_key');
|
||||
$this->storedRanges = array();
|
||||
|
||||
foreach ($this->ranges as $key => $range) {
|
||||
$this->storedRanges[$key] = clone($range);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
foreach ($this->ranges as $range) {
|
||||
$range->timeperiod_id = $this->object->id;
|
||||
$range->store($this->object->getConnection());
|
||||
}
|
||||
|
||||
foreach (array_diff(array_keys($this->storedRanges), array_keys($this->ranges)) as $delete) {
|
||||
$this->storedRanges[$delete]->delete();
|
||||
}
|
||||
|
||||
$this->storedRanges = $this->ranges;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getClass()
|
||||
{
|
||||
return __NAMESPACE__ . '\\IcingaTimePeriodRange';
|
||||
}
|
||||
|
||||
public static function loadForStoredObject(IcingaObject $object)
|
||||
{
|
||||
$ranges = new static($object);
|
||||
return $ranges->loadFromDb();
|
||||
}
|
||||
|
||||
public function toConfigString()
|
||||
{
|
||||
if (empty($this->ranges) && $this->object->object_type === 'template') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$string = " ranges = {\n";
|
||||
|
||||
foreach ($this->ranges as $range) {
|
||||
$string .= sprintf(
|
||||
" %s\t= %s\n",
|
||||
c::renderString($range->range_key),
|
||||
c::renderString($range->range_value)
|
||||
);
|
||||
}
|
||||
|
||||
return $string . " }\n";
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
return $this->toConfigString();
|
||||
} catch (Exception $e) {
|
||||
trigger_error($e);
|
||||
$previousHandler = set_exception_handler(
|
||||
function () {
|
||||
}
|
||||
);
|
||||
restore_error_handler();
|
||||
if ($previousHandler !== null) {
|
||||
call_user_func($previousHandler, $e);
|
||||
die();
|
||||
} else {
|
||||
die($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue