Skip to content
Open

SLA #710

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ jobs:
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
os: ['ubuntu-latest']

services:
mysql:
image: mariadb
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: icingadb_web_unittest
MYSQL_USER: icingadb_web_unittest
MYSQL_PASSWORD: icingadb_web_unittest
options: >-
--health-cmd "mysql -s -uroot -proot -e'SHOW DATABASES;' 2> /dev/null | grep icingadb_web_unittest > test"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 3306/tcp

steps:
- name: Checkout code base
uses: actions/checkout@v3
Expand All @@ -63,6 +79,7 @@ jobs:
with:
php-version: ${{ matrix.php }}
tools: phpunit:${{ matrix.phpunit-version || env.phpunit-version }}
extensions: mysql

- name: Setup Icinga Web
run: |
Expand All @@ -78,4 +95,5 @@ jobs:
- name: PHPUnit
env:
ICINGAWEB_LIBDIR: _libraries
ICINGADBWEB_TEST_MYSQL_PORT: ${{ job.services.mysql.ports['3306'] }}
run: phpunit --verbose --bootstrap _icingaweb2/test/php/bootstrap.php
5 changes: 5 additions & 0 deletions library/Icingadb/Model/Host.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ public function createRelations(Relations $relations)
$relations->belongsToMany('hostgroup', Hostgroup::class)
->through(HostgroupMember::class);

$relations->hasMany('sla_history_state', SlaHistoryState::class)
->setJoinType('LEFT');
$relations->hasMany('sla_history_downtime', SlaHistoryDowntime::class)
->setJoinType('LEFT');

$relations->hasOne('state', HostState::class)->setJoinType('LEFT');
$relations->hasMany('comment', Comment::class)->setJoinType('LEFT');
$relations->hasMany('downtime', Downtime::class)->setJoinType('LEFT');
Expand Down
137 changes: 137 additions & 0 deletions library/Icingadb/Model/HostSlaHistory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

/* Icinga DB Web | (c) 2023 Icinga GmbH | GPLv2 */

namespace Icinga\Module\Icingadb\Model;

use Icinga\Module\Icingadb\ProvidedHook\Reporting\Common\SlaTimeline;
use ipl\Orm\Relations;
use ipl\Orm\UnionModel;
use ipl\Sql\Connection;
use ipl\Sql\Expression;
use ipl\Stdlib\Filter;

class HostSlaHistory extends UnionModel
{
protected $slaEndTimes = [];

public function getTableName()
{
return 'host';
}

public function getKeyName()
{
return 'host_id';
}

public function getColumns()
{
return [
'host_id',
'display_name',
'event_time',
'event_type',
'hard_state',
'previous_hard_state'
];
}

public static function on(Connection $db, array $slaEndTimes = [])
{
$query = parent::on($db);
$query->getModel()->setSlaEndTimes($slaEndTimes);

$downtimeFilter = Filter::unlike('sla_history_downtime.service_id', '*');

$unions = $query->getUnions();
$unions[0]->filter($downtimeFilter);
$unions[1]->filter($downtimeFilter);
$unions[2]->filter(Filter::unlike('sla_history_state.service_id', '*'));

return $query;
}

public function getUnions()
{
$unions = [
[
Host::class,
[
'sla_history_downtime'
],
[
'display_name' => 'host.display_name',
'event_time' => 'sla_history_downtime.downtime_start',
'event_type' => new Expression(SlaTimeline::DOWNTIME_START),
'hard_state' => new Expression('NULL'),
'host_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
]
],
[
Host::class,
[
'sla_history_downtime'
],
[
'display_name' => 'host.display_name',
'event_time' => 'sla_history_downtime.downtime_end',
'event_type' => new Expression(SlaTimeline::DOWNTIME_END),
'hard_state' => new Expression('NULL'),
'host_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
]
],
[
Host::class,
[
'sla_history_state'
],
[
'display_name' => 'display_name',
'event_time' => 'sla_history_state.event_time',
'event_type' => new Expression(SlaTimeline::STATE_CHANGE),
'hard_state' => 'sla_history_state.hard_state',
'host_id' => 'id',
'previous_hard_state' => 'sla_history_state.previous_hard_state',
]
]
];

// Create a union part for all sla interval end times which is supposed to identify the end of the interval.
foreach ($this->slaEndTimes as $timerange) {
$unions[] = [
Host::class,
[],
[
'display_name' => 'host.display_name',
'event_time' => new Expression($timerange->end->format('Uv')),
'event_type' => new Expression(SlaTimeline::END_RESULT),
'hard_state' => new Expression('NULL'),
'host_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
]
];
}

return $unions;
}

public function getDefaultSort()
{
return ['event_time', 'display_name', 'event_type'];
}

public function createRelations(Relations $relations)
{
(new Host())->createRelations($relations);
}

public function setSlaEndTimes(array $times): self
{
$this->slaEndTimes = $times;

return $this;
}
}
5 changes: 5 additions & 0 deletions library/Icingadb/Model/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ public function createRelations(Relations $relations)
$relations->belongsToMany('hostgroup', Hostgroup::class)
->through(HostgroupMember::class);

$relations->hasMany('sla_history_state', SlaHistoryState::class)
->setJoinType('LEFT');
$relations->hasMany('sla_history_downtime', SlaHistoryDowntime::class)
->setJoinType('LEFT');

$relations->hasOne('state', ServiceState::class)->setJoinType('LEFT');
$relations->hasMany('comment', Comment::class)->setJoinType('LEFT');
$relations->hasMany('downtime', Downtime::class)->setJoinType('LEFT');
Expand Down
151 changes: 151 additions & 0 deletions library/Icingadb/Model/ServiceSlaHistory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

/* Icinga DB Web | (c) 2023 Icinga GmbH | GPLv2 */

namespace Icinga\Module\Icingadb\Model;

use Icinga\Module\Icingadb\ProvidedHook\Reporting\Common\SlaTimeline;
use ipl\Orm\Relations;
use ipl\Orm\UnionModel;
use ipl\Sql\Connection;
use ipl\Sql\Expression;

class ServiceSlaHistory extends UnionModel
{
protected $slaEndTimes = [];

public function getTableName()
{
return 'service';
}

public function getKeyName()
{
return ['host_id', 'service_id'];
}

public function getColumns()
{
return [
'host_id',
'service_id',
'display_name',
'host_display_name',
'event_time',
'event_type',
'hard_state',
'previous_hard_state'
];
}

public static function on(Connection $db, array $timeranges = [])
{
$query = parent::on($db);
$query->getModel()->setSlaEndTimes($timeranges);

return $query;
}

public function getUnions()
{
$unions = [
[
Service::class,
[
'host',
'sla_history_downtime'
],
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_time' => 'sla_history_downtime.downtime_start',
'event_type' => new Expression(SlaTimeline::DOWNTIME_START),
'hard_state' => new Expression('NULL'),
'host_id' => 'host.id',
'service_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
]
],
[
Service::class,
[
'host',
'sla_history_downtime'
],
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_time' => 'sla_history_downtime.downtime_end',
'event_type' => new Expression(SlaTimeline::DOWNTIME_END),
'hard_state' => new Expression('NULL'),
'host_id' => 'host.id',
'service_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
]
],
[
Service::class,
[
'host',
'sla_history_state'
],
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_time' => 'sla_history_state.event_time',
'event_type' => new Expression(SlaTimeline::STATE_CHANGE),
'hard_state' => 'sla_history_state.hard_state',
'host_id' => 'host.id',
'service_id' => 'id',
'previous_hard_state' => 'sla_history_state.previous_hard_state',
]
]
];

// Create a union part for all sla interval end times which is supposed to identify the end of the interval.
foreach ($this->slaEndTimes as $timerange) {
$unions[] = [
Service::class,
[
'host'
],
[
'display_name' => 'display_name',
'host_display_name' => 'host.display_name',
'event_time' => new Expression($timerange->end->format('Uv')),
'event_type' => new Expression(SlaTimeline::END_RESULT),
'hard_state' => new Expression('NULL'),
'host_id' => 'host.id',
'service_id' => 'id',
'previous_hard_state' => new Expression('NULL'),
]
];
}

return $unions;
}

public function getDefaultSort()
{
return ['event_time', 'host_display_name', 'display_name', 'event_type'];
}

public function createRelations(Relations $relations)
{
(new Service())->createRelations($relations);
}

/**
* Set all the sla interval end time to be part of the union query
*
* @param array $times
*
* @return $this
*/
public function setSlaEndTimes(array $times): self
{
$this->slaEndTimes = $times;

return $this;
}
}
8 changes: 8 additions & 0 deletions library/Icingadb/Model/ServiceState.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public function getKeyName()
return 'service_id';
}

public function getColumns()
{
$columns = parent::getColumns();
$columns[] = 'host_id';

return $columns;
}

public function getColumnDefinitions()
{
return [
Expand Down
Loading