Skip to content

Commit 978efc5

Browse files
authored
Merge pull request #108 from NETWAYS/group-downtime
Add custom queries for hostgroup and servicegroup to query downtimes
2 parents cd90e85 + c365912 commit 978efc5

7 files changed

Lines changed: 477 additions & 5 deletions

File tree

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
<?php
2+
3+
namespace Icinga\Module\Toplevelview\Model;
4+
5+
use Icinga\Module\Icingadb\Common\Auth;
6+
use Icinga\Module\Icingadb\Model\Host;
7+
use Icinga\Module\Icingadb\Model\Service;
8+
use Icinga\Module\Icingadb\Model\Hostgroup;
9+
10+
use ipl\Orm\Behavior\Binary;
11+
use ipl\Orm\Behaviors;
12+
use ipl\Orm\Query;
13+
use ipl\Orm\Relations;
14+
use ipl\Orm\UnionModel;
15+
use ipl\Orm\UnionQuery;
16+
use ipl\Sql\Adapter\Pgsql;
17+
use ipl\Sql\Connection;
18+
use ipl\Sql\Expression;
19+
use ipl\Sql\Select;
20+
21+
/**
22+
* Hostgroupsummary is a custom model we use to add more columns than the IcingaDB Hostgroupsummary
23+
*/
24+
class Hostgroupsummary extends UnionModel
25+
{
26+
public static function on(Connection $db): UnionQuery
27+
{
28+
$q = parent::on($db);
29+
30+
$q->on(
31+
Query::ON_SELECT_ASSEMBLED,
32+
function () use ($q) {
33+
$auth = new class () {
34+
use Auth;
35+
};
36+
37+
$auth->assertColumnRestrictions($q->getFilter());
38+
}
39+
);
40+
41+
$q->on($q::ON_SELECT_ASSEMBLED, function (Select $select) use ($q) {
42+
$model = $q->getModel();
43+
44+
$groupBy = $q->getResolver()->qualifyColumnsAndAliases((array) $model->getKeyName(), $model, false);
45+
46+
// For PostgreSQL, ALL non-aggregate SELECT columns must appear in the GROUP BY clause:
47+
if ($q->getDb()->getAdapter() instanceof Pgsql) {
48+
/**
49+
* Ignore Expressions, i.e. aggregate functions {@see getColumns()},
50+
* which do not need to be added to the GROUP BY.
51+
*/
52+
$candidates = array_filter($select->getColumns(), 'is_string');
53+
// Remove already considered columns for the GROUP BY, i.e. the primary key.
54+
$candidates = array_diff_assoc($candidates, $groupBy);
55+
$groupBy = array_merge($groupBy, $candidates);
56+
}
57+
58+
$select->groupBy($groupBy);
59+
});
60+
61+
return $q;
62+
}
63+
64+
public function getTableName()
65+
{
66+
return 'hostgroup';
67+
}
68+
69+
public function getKeyName()
70+
{
71+
return ['id' => 'hostgroup_id'];
72+
}
73+
74+
public function getColumns()
75+
{
76+
return [
77+
'name' => 'hostgroup_name',
78+
'name_ci' => 'hostgroup_name_ci',
79+
'display_name' => 'hostgroup_display_name',
80+
'hosts_down_handled' => new Expression(
81+
'SUM(CASE WHEN host_state = 1'
82+
. ' AND (host_handled = \'y\' OR host_reachable = \'n\') THEN 1 ELSE 0 END)'
83+
),
84+
'hosts_down_unhandled' => new Expression(
85+
'SUM(CASE WHEN host_state = 1'
86+
. ' AND host_handled = \'n\' AND host_reachable = \'y\' THEN 1 ELSE 0 END)'
87+
),
88+
'hosts_pending' => new Expression(
89+
'SUM(CASE WHEN host_state = 99 THEN 1 ELSE 0 END)'
90+
),
91+
'hosts_total' => new Expression(
92+
'SUM(CASE WHEN host_id IS NOT NULL THEN 1 ELSE 0 END)'
93+
),
94+
'hosts_up' => new Expression(
95+
'SUM(CASE WHEN host_state = 0 THEN 1 ELSE 0 END)'
96+
),
97+
'hosts_severity' => new Expression('MAX(host_severity)'),
98+
'services_critical_handled' => new Expression(
99+
'SUM(CASE WHEN service_state = 2'
100+
. ' AND (service_handled = \'y\' OR service_reachable = \'n\') THEN 1 ELSE 0 END)'
101+
),
102+
'services_critical_unhandled' => new Expression(
103+
'SUM(CASE WHEN service_state = 2'
104+
. ' AND service_handled = \'n\' AND service_reachable = \'y\' THEN 1 ELSE 0 END)'
105+
),
106+
'services_ok' => new Expression(
107+
'SUM(CASE WHEN service_state = 0 THEN 1 ELSE 0 END)'
108+
),
109+
'services_pending' => new Expression(
110+
'SUM(CASE WHEN service_state = 99 THEN 1 ELSE 0 END)'
111+
),
112+
'services_total' => new Expression(
113+
'SUM(CASE WHEN service_id IS NOT NULL THEN 1 ELSE 0 END)'
114+
),
115+
'services_unknown_handled' => new Expression(
116+
'SUM(CASE WHEN service_state = 3'
117+
. ' AND (service_handled = \'y\' OR service_reachable = \'n\') THEN 1 ELSE 0 END)'
118+
),
119+
'services_unknown_unhandled' => new Expression(
120+
'SUM(CASE WHEN service_state = 3'
121+
. ' AND service_handled = \'n\' AND service_reachable = \'y\' THEN 1 ELSE 0 END)'
122+
),
123+
'services_warning_handled' => new Expression(
124+
'SUM(CASE WHEN service_state = 1'
125+
. ' AND (service_handled = \'y\' OR service_reachable = \'n\') THEN 1 ELSE 0 END)'
126+
),
127+
'services_warning_unhandled' => new Expression(
128+
'SUM(CASE WHEN service_state = 1'
129+
. ' AND service_handled = \'n\' AND service_reachable = \'y\' THEN 1 ELSE 0 END)'
130+
),
131+
'hosts_downtime_handled' => new Expression(
132+
'SUM(CASE WHEN host_state != 1 AND host_in_downtime = \'y\' THEN 1 ELSE 0 END)'
133+
),
134+
'hosts_downtime_active' => new Expression(
135+
'SUM(CASE WHEN host_in_downtime = \'y\' THEN 1 ELSE 0 END)'
136+
),
137+
'services_downtime_handled' => new Expression(
138+
'SUM(CASE WHEN service_state != 1 AND service_in_downtime = \'y\' THEN 1 ELSE 0 END)'
139+
),
140+
'services_downtime_active' => new Expression(
141+
'SUM(CASE WHEN service_in_downtime = \'y\' THEN 1 ELSE 0 END)'
142+
),
143+
];
144+
}
145+
146+
public function getSearchColumns()
147+
{
148+
return ['name_ci', 'display_name'];
149+
}
150+
151+
public function getDefaultSort()
152+
{
153+
return 'display_name';
154+
}
155+
156+
public function getUnions(): array
157+
{
158+
$unions = [
159+
[
160+
Host::class,
161+
[
162+
'hostgroup',
163+
'state'
164+
],
165+
[
166+
'hostgroup_id' => 'hostgroup.id',
167+
'hostgroup_name' => 'hostgroup.name',
168+
'hostgroup_name_ci' => 'hostgroup.name_ci',
169+
'hostgroup_display_name' => 'hostgroup.display_name',
170+
'host_id' => 'host.id',
171+
'host_state' => 'state.soft_state',
172+
'host_handled' => 'state.is_handled',
173+
'host_reachable' => 'state.is_reachable',
174+
'host_severity' => 'state.severity',
175+
'host_in_downtime' => 'state.in_downtime',
176+
'service_id' => new Expression('NULL'),
177+
'service_state' => new Expression('NULL'),
178+
'service_handled' => new Expression('NULL'),
179+
'service_reachable' => new Expression('NULL'),
180+
'service_in_downtime' => new Expression('NULL'),
181+
]
182+
],
183+
[
184+
Service::class,
185+
[
186+
'hostgroup',
187+
'state'
188+
],
189+
[
190+
'hostgroup_id' => 'hostgroup.id',
191+
'hostgroup_name' => 'hostgroup.name',
192+
'hostgroup_name_ci' => 'hostgroup.name_ci',
193+
'hostgroup_display_name' => 'hostgroup.display_name',
194+
'host_id' => new Expression('NULL'),
195+
'host_state' => new Expression('NULL'),
196+
'host_handled' => new Expression('NULL'),
197+
'host_reachable' => new Expression('NULL'),
198+
'host_in_downtime' => new Expression('NULL'),
199+
'host_severity' => new Expression('0'),
200+
'service_id' => 'service.id',
201+
'service_state' => 'state.soft_state',
202+
'service_handled' => 'state.is_handled',
203+
'service_reachable' => 'state.is_reachable',
204+
'service_in_downtime' => 'state.in_downtime',
205+
]
206+
],
207+
[
208+
Hostgroup::class,
209+
[],
210+
[
211+
'hostgroup_id' => 'hostgroup.id',
212+
'hostgroup_name' => 'hostgroup.name',
213+
'hostgroup_name_ci' => 'hostgroup.name_ci',
214+
'hostgroup_display_name' => 'hostgroup.display_name',
215+
'host_id' => new Expression('NULL'),
216+
'host_state' => new Expression('NULL'),
217+
'host_handled' => new Expression('NULL'),
218+
'host_reachable' => new Expression('NULL'),
219+
'host_severity' => new Expression('0'),
220+
'host_in_downtime' => new Expression('NULL'),
221+
'service_id' => new Expression('NULL'),
222+
'service_state' => new Expression('NULL'),
223+
'service_handled' => new Expression('NULL'),
224+
'service_reachable' => new Expression('NULL'),
225+
'service_in_downtime' => new Expression('NULL'),
226+
]
227+
]
228+
];
229+
230+
return $unions;
231+
}
232+
233+
public function createBehaviors(Behaviors $behaviors)
234+
{
235+
$behaviors->add(new Binary([
236+
'id'
237+
]));
238+
239+
// This is because there is no better way
240+
(new Hostgroup())->createBehaviors($behaviors);
241+
}
242+
243+
public function createRelations(Relations $relations)
244+
{
245+
// This is because there is no better way
246+
(new Hostgroup())->createRelations($relations);
247+
}
248+
249+
public function getColumnDefinitions()
250+
{
251+
// This is because there is no better way
252+
return (new Hostgroup())->getColumnDefinitions();
253+
}
254+
}

0 commit comments

Comments
 (0)