Merge branch 'feature/behaviors'

This commit is contained in:
Eric Lippmann 2019-10-15 13:48:51 +02:00
commit 6e2c4d3d1e
12 changed files with 134 additions and 88 deletions

View file

@ -22,7 +22,6 @@ class HostsController extends Controller
$hosts->limit($limitControl->getLimit());
$hostList = (new HostList($hosts))
->setRedis($this->getRedis())
->setViewMode($viewModeSwitcher->getViewMode());
$this->addControl($this->createPaginationControl($hosts));

View file

@ -5,7 +5,6 @@ namespace Icinga\Module\Eagle\Controllers;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Eagle\Common\CommandActions;
use Icinga\Module\Eagle\Model\Service;
use Icinga\Module\Eagle\Redis\VolatileState;
use Icinga\Module\Eagle\Web\Controller;
use Icinga\Module\Eagle\Widget\ServiceListItem;
@ -36,10 +35,6 @@ class ServiceController extends Controller
throw new NotFoundError($this->translate('Service not found'));
}
$volatileState = new VolatileState($this->getRedis());
$volatileState->add($service);
$volatileState->fetch();
$this->service = $service;
}

View file

@ -26,7 +26,6 @@ class ServicesController extends Controller
$services->limit($limitControl->getLimit());
$serviceList = (new ServiceList($services))
->setRedis($this->getRedis())
->setViewMode($viewModeSwitcher->getViewMode());
$this->addControl($this->createPaginationControl($services));

View file

@ -0,0 +1,11 @@
<?php
namespace Icinga\Module\Eagle\Model\Behavior;
class BoolCast extends PropertiesBehavior
{
public function __invoke($value, $key)
{
return $value === 'y';
}
}

View file

@ -0,0 +1,25 @@
<?php
namespace Icinga\Module\Eagle\Model\Behavior;
use ipl\Orm\Contract\BehaviorInterface;
use ipl\Orm\Model;
abstract class PropertiesBehavior implements BehaviorInterface
{
protected $properties;
public function __construct(array $properties)
{
$this->properties = $properties;
}
public function apply(Model $model)
{
foreach ($this->properties as $key) {
$model[$key] = $this($model[$key], $key);
}
}
abstract public function __invoke($value, $key);
}

View file

@ -0,0 +1,11 @@
<?php
namespace Icinga\Module\Eagle\Model\Behavior;
class Timestamp extends PropertiesBehavior
{
public function __invoke($value, $key)
{
return $value / 1000.0;
}
}

View file

@ -0,0 +1,36 @@
<?php
namespace Icinga\Module\Eagle\Model\Behavior;
use Icinga\Application\Config;
use Icinga\Module\Eagle\Redis\VolatileState as RedisState;
use ipl\Orm\Contract\BehaviorInterface;
use ipl\Orm\Model;
use Redis;
class VolatileState implements BehaviorInterface
{
protected $state;
protected function getVolatileState()
{
if ($this->state === null) {
// TODO(jmeyer): Use a service provider here. (Or something similar)
$config = Config::module('eagle')->getSection('redis');
$redis = new Redis();
$redis->connect(
$config->get('host', 'redis'),
$config->get('port', 6379)
);
$this->state = new RedisState($redis);
}
return $this->state;
}
public function apply(Model $model)
{
$this->getVolatileState()->fetch($model);
}
}

View file

@ -2,6 +2,8 @@
namespace Icinga\Module\Eagle\Model;
use Icinga\Module\Eagle\Model\Behavior\BoolCast;
use ipl\Orm\Behaviors;
use ipl\Orm\Model;
use ipl\Orm\Relations;
@ -66,6 +68,17 @@ class Host extends Model
];
}
public function createBehaviors(Behaviors $behaviors)
{
$behaviors->add(new BoolCast([
'active_checks_enabled',
'passive_checks_enabled',
'event_handler_enabled',
'notifications_enabled',
'flapping_enabled'
]));
}
public function createRelations(Relations $relations)
{
$relations->belongsTo('environment', Environment::class);

View file

@ -2,6 +2,8 @@
namespace Icinga\Module\Eagle\Model;
use Icinga\Module\Eagle\Model\Behavior\BoolCast;
use ipl\Orm\Behaviors;
use ipl\Orm\Model;
use ipl\Orm\Relations;
@ -60,6 +62,17 @@ class Service extends Model
];
}
public function createBehaviors(Behaviors $behaviors)
{
$behaviors->add(new BoolCast([
'active_checks_enabled',
'passive_checks_enabled',
'event_handler_enabled',
'notifications_enabled',
'flapping_enabled'
]));
}
public function createRelations(Relations $relations)
{
$relations->belongsTo('environment', Environment::class);

View file

@ -2,6 +2,9 @@
namespace Icinga\Module\Eagle\Model;
use Icinga\Module\Eagle\Model\Behavior\Timestamp;
use Icinga\Module\Eagle\Model\Behavior\VolatileState;
use ipl\Orm\Behaviors;
use ipl\Orm\Model;
/**
@ -43,6 +46,19 @@ abstract class State extends Model
];
}
public function createBehaviors(Behaviors $behaviors)
{
$behaviors->add(new VolatileState());
$behaviors->add(new Timestamp([
'last_update',
'last_state_change',
'last_soft_state',
'last_hard_state',
'next_check',
'next_update'
]));
}
public function mutateIsOverdueProperty()
{
return $this->properties['next_update'] < time();

View file

@ -2,7 +2,7 @@
namespace Icinga\Module\Eagle\Redis;
use ipl\Orm\Model;
use Icinga\Module\Eagle\Model\State;
/**
* Fetch volatile host or service states from redis.
@ -12,12 +12,6 @@ class VolatileState
/** @var \Redis */
protected $redis;
/** @var string */
protected $type;
/** @var array */
protected $objects = [];
/** @var array Set of keys to sync */
public static $keys = [
'attempt',
@ -44,48 +38,22 @@ class VolatileState
}
/**
* Add an object to fetch volatile states for
* Fetch volatile state
*
* @param Model $object
* @param State $state
*
* @return $this
*/
public function add(Model $object)
public function fetch(State $state)
{
$this->objects[bin2hex($object->id)] = $object;
if ($this->type === null) {
$this->type = $object->getTableName();
}
return $this;
}
/**
* Fetch volatile states
*
* @return $this
*/
public function fetch()
{
$keys = array_keys($this->objects);
if (empty($keys)) {
return $this;
}
$rs = array_combine($keys, $this->redis->hMGet("icinga:config:state:{$this->type}", $keys));
foreach ($rs as $key => $json) {
if ($json === false) {
continue;
}
$type = substr($state->getTableName(), 0, -6);
$json = $this->redis->hGet("icinga:config:state:{$type}", bin2hex($state->{$type . '_id'}));
if ($json !== false) {
$data = json_decode($json, true);
$data = array_intersect_key($data, array_flip(static::$keys));
$this->objects[$key]->state->setProperties($data);
$state->setProperties($data);
}
return $this;

View file

@ -3,55 +3,15 @@
namespace Icinga\Module\Eagle\Widget;
use Icinga\Module\Eagle\Common\ViewMode;
use Icinga\Module\Eagle\Redis\VolatileState;
use Redis;
abstract class StateList extends BaseItemList
{
use ViewMode;
/** @var iterable Data source of the list */
protected $data;
/** @var Redis Redis connection to fetch volatile states from */
protected $redis;
/**
* Set the Redis connection to fetch volatile states from
*
* @param Redis $redis
*
* @return $this
*/
public function setRedis(Redis $redis)
{
$this->redis = $redis;
return $this;
}
/**
* Get the helper to fetch volatile states
*
* @return VolatileState
*/
public function getVolatileState()
{
return new VolatileState($this->redis);
}
protected function assemble()
{
$this->addAttributes(['class' => $this->getViewMode()]);
$itemClass = $this->getItemClass();
$volatileState = $this->getVolatileState();
foreach ($this->data as $object) {
$volatileState->add($object);
$this->add(new $itemClass($object));
}
$volatileState->fetch();
parent::assemble();
}
}