2015-04-24 14:26:44 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Icinga\Module\Director;
|
|
|
|
|
|
|
|
use Icinga\Data\Db\DbConnection;
|
2015-08-29 01:05:23 +02:00
|
|
|
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
|
2016-02-09 20:38:16 +01:00
|
|
|
use Icinga\Module\Director\Objects\IcingaEndpoint;
|
2016-02-27 12:07:50 +01:00
|
|
|
use Icinga\Module\Director\Objects\IcingaObject;
|
2016-03-02 21:47:37 +01:00
|
|
|
use Icinga\Module\Director\Util;
|
2016-02-09 20:38:16 +01:00
|
|
|
use Icinga\Exception\ConfigurationError;
|
2015-08-28 18:02:44 +02:00
|
|
|
use Zend_Db_Expr;
|
2015-12-18 09:05:04 +01:00
|
|
|
use Zend_Db_Select;
|
2015-04-24 14:26:44 +02:00
|
|
|
|
|
|
|
class Db extends DbConnection
|
|
|
|
{
|
|
|
|
protected $modules = array();
|
|
|
|
|
2015-06-08 14:37:02 +02:00
|
|
|
protected static $zoneCache;
|
|
|
|
|
|
|
|
protected static $commandCache;
|
|
|
|
|
2016-02-09 20:14:18 +01:00
|
|
|
protected $settings;
|
|
|
|
|
2015-04-24 14:26:44 +02:00
|
|
|
protected function db()
|
|
|
|
{
|
|
|
|
return $this->getDbAdapter();
|
|
|
|
}
|
|
|
|
|
2016-02-27 12:07:50 +01:00
|
|
|
public function countActivitiesSinceLastDeployedConfig(IcingaObject $object = null)
|
2016-02-18 13:46:24 +01:00
|
|
|
{
|
2016-02-27 12:07:50 +01:00
|
|
|
$db = $this->db();
|
|
|
|
|
2016-03-13 22:27:47 +01:00
|
|
|
$query = 'SELECT COUNT(*) FROM director_activity_log WHERE id > COALESCE(('
|
2016-02-18 13:46:24 +01:00
|
|
|
. ' SELECT id FROM director_activity_log WHERE checksum = ('
|
|
|
|
. ' SELECT last_activity_checksum FROM director_generated_config WHERE checksum = ('
|
|
|
|
. ' SELECT config_checksum FROM director_deployment_log ORDER by id desc limit 1'
|
|
|
|
. ' )'
|
|
|
|
. ' )'
|
2016-03-13 22:27:47 +01:00
|
|
|
. '), 0)';
|
2016-02-18 13:46:24 +01:00
|
|
|
|
2016-02-27 12:07:50 +01:00
|
|
|
if ($object !== null) {
|
|
|
|
$query .= $db->quoteInto(' AND object_type = ?', $object->getTableName());
|
|
|
|
$query .= $db->quoteInto(' AND object_name = ?', $object->object_name);
|
|
|
|
}
|
|
|
|
return (int) $db->fetchOne($query);
|
2016-02-18 13:46:24 +01:00
|
|
|
}
|
|
|
|
|
2016-03-16 22:45:29 +01:00
|
|
|
// TODO: use running config?!
|
|
|
|
public function getLastDeploymentActivityLogId()
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
|
|
|
|
$query = ' SELECT COALESCE(id, 0) AS id FROM director_activity_log WHERE checksum = ('
|
|
|
|
. ' SELECT last_activity_checksum FROM director_generated_config WHERE checksum = ('
|
|
|
|
. ' SELECT config_checksum FROM director_deployment_log ORDER by id desc limit 1'
|
|
|
|
. ' )'
|
|
|
|
. ')';
|
|
|
|
|
|
|
|
return (int) $db->fetchOne($query);
|
|
|
|
}
|
|
|
|
|
2016-02-09 20:38:16 +01:00
|
|
|
public function getMasterZoneName()
|
|
|
|
{
|
2016-03-02 23:32:25 +01:00
|
|
|
if ($zone = $this->getSetting('master_zone')) {
|
|
|
|
return $zone;
|
|
|
|
}
|
|
|
|
|
|
|
|
$db = $this->db();
|
|
|
|
$query = $db->select()
|
|
|
|
->from('icinga_zone', 'object_name')
|
|
|
|
->where('is_global = ?', 'n');
|
|
|
|
|
|
|
|
$zones = $db->fetchCol($query);
|
|
|
|
|
|
|
|
if (count($zones) === 1) {
|
|
|
|
return $zones[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'master';
|
2016-02-09 20:38:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getDefaultGlobalZoneName()
|
|
|
|
{
|
|
|
|
return $this->getSetting('default_global_zone', 'director-global');
|
|
|
|
}
|
|
|
|
|
2016-03-02 22:51:50 +01:00
|
|
|
public function hasDeploymentEndpoint()
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
$query = $db->select()->from(
|
|
|
|
array('z' => 'icinga_zone'),
|
|
|
|
array('cnt' => 'COUNT(*)')
|
|
|
|
)->join(
|
|
|
|
array('e' => 'icinga_endpoint'),
|
|
|
|
'e.zone_id = z.id',
|
|
|
|
array()
|
|
|
|
)->join(
|
|
|
|
array('au' => 'icinga_apiuser'),
|
|
|
|
'e.apiuser_id = au.id',
|
|
|
|
array()
|
|
|
|
)->where('z.object_name = ?', $this->getMasterZoneName());
|
|
|
|
|
|
|
|
return $db->fetchOne($query) > 0;
|
|
|
|
}
|
|
|
|
|
2016-02-09 20:38:16 +01:00
|
|
|
public function getDeploymentEndpointName()
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
$query = $db->select()->from(
|
2016-02-17 16:42:42 +01:00
|
|
|
array('z' => 'icinga_zone'),
|
2016-02-09 20:38:16 +01:00
|
|
|
array('object_name' => 'e.object_name')
|
|
|
|
)->join(
|
2016-02-17 16:42:42 +01:00
|
|
|
array('e' => 'icinga_endpoint'),
|
|
|
|
'e.zone_id = z.id',
|
|
|
|
array()
|
|
|
|
)->join(
|
|
|
|
array('au' => 'icinga_apiuser'),
|
|
|
|
'e.apiuser_id = au.id',
|
|
|
|
array()
|
2016-02-09 20:38:16 +01:00
|
|
|
)->where('z.object_name = ?', $this->getMasterZoneName())
|
|
|
|
->order('e.object_name ASC')
|
|
|
|
->limit(1);
|
|
|
|
|
|
|
|
$name = $db->fetchOne($query);
|
2016-03-02 22:26:42 +01:00
|
|
|
|
2016-02-09 20:38:16 +01:00
|
|
|
if (! $name) {
|
|
|
|
throw new ConfigurationError(
|
2016-03-02 22:26:42 +01:00
|
|
|
'Unable to detect your deployment endpoint. I was looking for'
|
2016-03-03 01:47:32 +01:00
|
|
|
. ' the first endpoint configured with an assigned API user'
|
|
|
|
. ' in the "%s" zone.',
|
2016-03-02 22:26:42 +01:00
|
|
|
$this->getMasterZoneName()
|
2016-02-09 20:38:16 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDeploymentEndpoint()
|
|
|
|
{
|
|
|
|
return IcingaEndpoint::load($this->getDeploymentEndpointName(), $this);
|
|
|
|
}
|
|
|
|
|
2016-02-09 20:14:18 +01:00
|
|
|
public function getSetting($name, $default = null)
|
|
|
|
{
|
|
|
|
if ($this->settings === null) {
|
|
|
|
$this->fetchSettings();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (array_key_exists($name, $this->settings)) {
|
|
|
|
return $this->settings[$name];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $default;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function storeSetting($name, $value)
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
2016-03-24 13:23:41 +01:00
|
|
|
if ($this->getSetting($name) === $value) {
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2016-02-09 20:14:18 +01:00
|
|
|
$updated = $db->update(
|
|
|
|
'director_setting',
|
|
|
|
array('setting_value' => $value),
|
|
|
|
$db->quoteInto('setting_name = ?', $name)
|
|
|
|
);
|
|
|
|
|
|
|
|
if ($updated === 0) {
|
|
|
|
$db->insert(
|
|
|
|
'director_setting',
|
|
|
|
array(
|
|
|
|
'setting_name' => $name,
|
|
|
|
'setting_value' => $value,
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->settings !== null) {
|
|
|
|
$this->settings[$name] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function fetchSettings($force = true)
|
|
|
|
{
|
|
|
|
if ($force || $this->settings === null) {
|
|
|
|
$db = $this->db();
|
|
|
|
$query = $db->select()->from(
|
|
|
|
array('s' => 'director_setting'),
|
|
|
|
array('setting_name', 'setting_value')
|
|
|
|
);
|
|
|
|
$this->settings = (array) $db->fetchPairs($query);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->settings;
|
|
|
|
}
|
|
|
|
|
2015-11-17 21:14:33 +01:00
|
|
|
public function getActivitylogNeighbors($id, $type = null, $name = null)
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
|
|
|
|
$greater = $db->select()->from(
|
|
|
|
array('g' => 'director_activity_log'),
|
|
|
|
array('id' => 'MIN(g.id)')
|
|
|
|
)->where('id > ?', (int) $id);
|
|
|
|
|
|
|
|
$smaller = $db->select()->from(
|
|
|
|
array('l' => 'director_activity_log'),
|
|
|
|
array('id' => 'MAX(l.id)')
|
|
|
|
)->where('id < ?', (int) $id);
|
|
|
|
|
|
|
|
if ($type !== null) {
|
|
|
|
$greater->where('object_type = ?', $type);
|
|
|
|
$smaller->where('object_type = ?', $type);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($name !== null) {
|
|
|
|
$greater->where('object_name = ?', $name);
|
|
|
|
$smaller->where('object_name = ?', $name);
|
|
|
|
}
|
|
|
|
|
|
|
|
$query = $db->select()->from(
|
|
|
|
array('gt' => $greater),
|
|
|
|
array(
|
|
|
|
'prev' => 'lt.id',
|
|
|
|
'next' => 'gt.id'
|
2016-02-26 11:58:37 +01:00
|
|
|
)
|
2015-11-17 21:14:33 +01:00
|
|
|
)->join(
|
|
|
|
array('lt' => $smaller),
|
2016-03-01 04:20:39 +01:00
|
|
|
'1 = 1',
|
2015-11-17 21:14:33 +01:00
|
|
|
array()
|
|
|
|
);
|
|
|
|
|
|
|
|
return $db->fetchRow($query);
|
|
|
|
}
|
|
|
|
|
2015-06-18 11:01:45 +02:00
|
|
|
public function fetchActivityLogEntryById($id)
|
2015-06-01 14:33:07 +02:00
|
|
|
{
|
2016-03-02 21:40:12 +01:00
|
|
|
$sql = 'SELECT id, object_type, object_name, action_name,'
|
|
|
|
. ' old_properties, new_properties, author, change_time,'
|
|
|
|
. ' %s AS checksum, %s AS parent_checksum'
|
|
|
|
. ' FROM director_activity_log WHERE id = %d';
|
|
|
|
|
|
|
|
$sql = sprintf(
|
|
|
|
$sql,
|
|
|
|
$this->dbHexFunc('checksum'),
|
|
|
|
$this->dbHexFunc('parent_checksum'),
|
|
|
|
$id
|
|
|
|
);
|
2016-03-01 04:20:39 +01:00
|
|
|
|
2016-03-02 21:40:12 +01:00
|
|
|
return $this->db()->fetchRow($sql);
|
2015-06-01 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
2016-02-24 11:08:30 +01:00
|
|
|
public function fetchActivityLogChecksumById($id, $binary = true)
|
|
|
|
{
|
2016-03-02 21:47:37 +01:00
|
|
|
$sql = sprintf(
|
|
|
|
'SELECT %s AS checksum FROM director_activity_log WHERE id = %d',
|
|
|
|
$this->dbHexFunc('checksum'),
|
|
|
|
(int) $id
|
|
|
|
);
|
|
|
|
|
2016-02-24 11:08:30 +01:00
|
|
|
$result = $this->db()->fetchOne($sql);
|
|
|
|
|
|
|
|
if ($binary) {
|
2016-03-02 21:47:37 +01:00
|
|
|
return Util::hex2binary($result);
|
2016-02-24 11:08:30 +01:00
|
|
|
} else {
|
2016-03-02 21:47:37 +01:00
|
|
|
return $result;
|
2016-02-24 11:08:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-24 11:38:11 +01:00
|
|
|
public function fetchActivityLogIdByChecksum($checksum)
|
|
|
|
{
|
|
|
|
$sql = 'SELECT id FROM director_activity_log WHERE checksum = ?';
|
2016-05-23 15:40:12 +02:00
|
|
|
return $this->db()->fetchOne(
|
|
|
|
$this->db()->quoteInto($sql, $this->quoteBinary($checksum))
|
|
|
|
);
|
2016-02-24 11:38:11 +01:00
|
|
|
}
|
|
|
|
|
2015-06-18 11:01:45 +02:00
|
|
|
public function fetchActivityLogEntry($checksum)
|
2015-06-23 16:45:25 +02:00
|
|
|
{
|
2016-03-06 14:34:25 +01:00
|
|
|
$sql = 'SELECT id, object_type, object_name, action_name,'
|
|
|
|
. ' old_properties, new_properties, author, change_time,'
|
2016-03-02 21:40:12 +01:00
|
|
|
. ' %s AS checksum, %s AS parent_checksum'
|
|
|
|
. ' FROM director_activity_log WHERE checksum = ?';
|
2015-06-23 16:45:25 +02:00
|
|
|
|
2016-03-06 14:34:25 +01:00
|
|
|
$sql = sprintf(
|
|
|
|
$sql,
|
|
|
|
$this->dbHexFunc('checksum'),
|
2016-03-09 09:46:10 +01:00
|
|
|
$this->dbHexFunc('parent_checksum')
|
|
|
|
);
|
2016-03-06 14:34:25 +01:00
|
|
|
|
2016-03-02 21:54:38 +01:00
|
|
|
return $this->db()->fetchRow(
|
|
|
|
$sql,
|
|
|
|
$this->quoteBinary(Util::hex2binary($checksum))
|
|
|
|
);
|
2015-06-18 11:01:45 +02:00
|
|
|
}
|
|
|
|
|
2015-04-24 15:57:01 +02:00
|
|
|
public function getLastActivityChecksum()
|
|
|
|
{
|
2016-03-02 21:40:12 +01:00
|
|
|
$select = "SELECT checksum FROM (SELECT * FROM (SELECT 1 AS pos, "
|
|
|
|
. $this->dbHexFunc('checksum')
|
|
|
|
. " AS checksum"
|
|
|
|
. " FROM director_activity_log ORDER BY id DESC LIMIT 1) a"
|
|
|
|
. " UNION SELECT 2 AS pos, '' AS checksum) u ORDER BY pos LIMIT 1";
|
2015-04-24 15:57:01 +02:00
|
|
|
|
|
|
|
return $this->db()->fetchOne($select);
|
|
|
|
}
|
|
|
|
|
2015-07-27 22:39:29 +02:00
|
|
|
public function fetchImportStatistics()
|
|
|
|
{
|
|
|
|
$query = "SELECT 'imported_properties' AS stat_name, COUNT(*) AS stat_value"
|
|
|
|
. " FROM import_run i"
|
|
|
|
. " JOIN imported_rowset_row rs ON i.rowset_checksum = rs.rowset_checksum"
|
|
|
|
. " JOIN imported_row_property rp ON rp.row_checksum = rs.row_checksum"
|
|
|
|
. " UNION ALL"
|
|
|
|
. " SELECT 'imported_rows' AS stat_name, COUNT(*) AS stat_value"
|
|
|
|
. " FROM import_run i"
|
|
|
|
. " JOIN imported_rowset_row rs ON i.rowset_checksum = rs.rowset_checksum"
|
|
|
|
. " UNION ALL"
|
|
|
|
. " SELECT 'unique_rows' AS stat_name, COUNT(*) AS stat_value"
|
|
|
|
. " FROM imported_row"
|
|
|
|
. " UNION ALL"
|
|
|
|
. " SELECT 'unique_properties' AS stat_name, COUNT(*) AS stat_value"
|
|
|
|
. " FROM imported_property"
|
|
|
|
;
|
|
|
|
return $this->db()->fetchPairs($query);
|
|
|
|
}
|
|
|
|
|
2015-07-26 15:36:32 +02:00
|
|
|
public function getImportrunRowsetChecksum($id)
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
$query = $db->select()
|
2016-03-15 17:55:59 +01:00
|
|
|
->from(array('r' => 'import_run'), $this->dbHexFunc('r.rowset_checksum'))
|
|
|
|
->where('r.id = ?', $id);
|
2015-07-26 15:36:32 +02:00
|
|
|
|
|
|
|
return $db->fetchOne($query);
|
|
|
|
}
|
|
|
|
|
2015-08-02 13:29:20 +02:00
|
|
|
protected function fetchTemplateRelations($type)
|
2015-07-29 17:19:45 +02:00
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
$query = $db->select()->from(
|
2015-07-30 08:19:34 +02:00
|
|
|
array('p' => 'icinga_' . $type),
|
2015-07-29 17:19:45 +02:00
|
|
|
array(
|
2015-07-30 08:19:34 +02:00
|
|
|
'name' => 'o.object_name',
|
|
|
|
'parent' => 'p.object_name'
|
2015-07-29 17:19:45 +02:00
|
|
|
)
|
|
|
|
)->join(
|
2015-07-30 08:19:34 +02:00
|
|
|
array('i' => 'icinga_' . $type . '_inheritance'),
|
|
|
|
'p.id = i.parent_' . $type . '_id',
|
2015-07-29 17:19:45 +02:00
|
|
|
array()
|
|
|
|
)->join(
|
2015-07-30 08:19:34 +02:00
|
|
|
array('o' => 'icinga_' . $type),
|
|
|
|
'o.id = i.' . $type . '_id',
|
2015-07-29 17:19:45 +02:00
|
|
|
array()
|
2015-07-30 08:19:34 +02:00
|
|
|
)->where("o.object_type = 'template'")
|
|
|
|
->order('p.object_name')
|
|
|
|
->order('o.object_name');
|
2015-07-29 17:19:45 +02:00
|
|
|
|
2015-08-02 13:29:20 +02:00
|
|
|
return $db->fetchAll($query);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function fetchTemplateTree($type)
|
|
|
|
{
|
|
|
|
$relations = $this->fetchTemplateRelations($type);
|
2015-07-29 17:19:45 +02:00
|
|
|
$children = array();
|
2015-07-30 08:19:34 +02:00
|
|
|
$objects = array();
|
2015-07-29 17:19:45 +02:00
|
|
|
foreach ($relations as $rel) {
|
2015-07-30 08:19:34 +02:00
|
|
|
foreach (array('name', 'parent') as $col) {
|
|
|
|
if (! array_key_exists($rel->$col, $objects)) {
|
|
|
|
$objects[$rel->$col] = (object) array(
|
2015-07-29 17:19:45 +02:00
|
|
|
'name' => $rel->$col,
|
|
|
|
'children' => array()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-30 08:19:34 +02:00
|
|
|
|
2015-07-29 17:19:45 +02:00
|
|
|
foreach ($relations as $rel) {
|
2015-07-30 08:19:34 +02:00
|
|
|
$objects[$rel->parent]->children[$rel->name] = $objects[$rel->name];
|
|
|
|
$children[$rel->name] = $rel->parent;
|
2015-07-29 17:19:45 +02:00
|
|
|
}
|
|
|
|
|
2015-07-30 08:19:34 +02:00
|
|
|
foreach ($children as $name => $object) {
|
|
|
|
unset($objects[$name]);
|
2015-07-29 17:19:45 +02:00
|
|
|
}
|
|
|
|
|
2015-07-30 08:19:34 +02:00
|
|
|
return $objects;
|
2015-07-29 17:19:45 +02:00
|
|
|
}
|
|
|
|
|
2015-11-25 21:01:11 +01:00
|
|
|
public function fetchLatestImportedRows($source, $desiredColumns = null)
|
2015-07-22 23:33:24 +02:00
|
|
|
{
|
|
|
|
$db = $this->db();
|
2015-11-25 21:01:11 +01:00
|
|
|
if ($desiredColumns === null) {
|
|
|
|
$columns = null;
|
|
|
|
} else {
|
|
|
|
$columns = array();
|
|
|
|
foreach ($desiredColumns as $column) {
|
|
|
|
if (false === ($pos = strpos($column, '.'))) {
|
|
|
|
$columns[$column] = $column;
|
|
|
|
} else {
|
|
|
|
$column = substr($column, 0, $pos);
|
|
|
|
$columns[$column] = $column;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-05 20:01:31 +01:00
|
|
|
$lastRun = $db->select()->from(
|
2016-03-15 17:55:59 +01:00
|
|
|
array('r' => 'import_run'),
|
|
|
|
array('checksum' => $this->dbHexFunc('r.rowset_checksum'))
|
2016-03-05 20:01:31 +01:00
|
|
|
);
|
2015-07-22 23:33:24 +02:00
|
|
|
|
|
|
|
if (is_int($source) || ctype_digit($source)) {
|
2016-03-15 17:55:59 +01:00
|
|
|
$lastRun->where('r.source_id = ?', $source);
|
2015-07-22 23:33:24 +02:00
|
|
|
} else {
|
2016-03-15 17:55:59 +01:00
|
|
|
$lastRun->where('r.source_name = ?', $source);
|
2015-07-22 23:33:24 +02:00
|
|
|
}
|
|
|
|
|
2016-03-15 17:55:59 +01:00
|
|
|
$lastRun->order('r.start_time DESC')->limit(1);
|
2015-07-22 23:33:24 +02:00
|
|
|
$checksum = $db->fetchOne($lastRun);
|
|
|
|
|
|
|
|
return $this->fetchImportedRowsetRows($checksum, $columns);
|
|
|
|
}
|
|
|
|
|
2016-03-18 13:43:15 +01:00
|
|
|
public function fetchImportedRowsetRows($checksum, $columns, $filter = null)
|
2015-11-25 21:54:42 +01:00
|
|
|
{
|
|
|
|
$db = $this->db();
|
2016-03-05 20:01:31 +01:00
|
|
|
$binchecksum = Util::hex2binary($checksum);
|
|
|
|
|
2015-11-25 21:54:42 +01:00
|
|
|
$query = $db->select()->from(
|
|
|
|
array('rsr' => 'imported_rowset_row'),
|
|
|
|
array(
|
|
|
|
'object_name' => 'r.object_name',
|
|
|
|
'property_name' => 'p.property_name',
|
|
|
|
'property_value' => 'p.property_value',
|
|
|
|
'format' => 'p.format'
|
|
|
|
)
|
|
|
|
)->join(
|
|
|
|
array('r' => 'imported_row'),
|
|
|
|
'rsr.row_checksum = r.checksum',
|
|
|
|
array()
|
|
|
|
)->join(
|
|
|
|
array('rp' => 'imported_row_property'),
|
|
|
|
'r.checksum = rp.row_checksum',
|
|
|
|
array()
|
|
|
|
)->join(
|
|
|
|
array('p' => 'imported_property'),
|
|
|
|
'p.checksum = rp.property_checksum',
|
|
|
|
array()
|
2016-03-05 20:01:31 +01:00
|
|
|
)->where('rsr.rowset_checksum = ?', $this->quoteBinary($binchecksum))->order('r.object_name');
|
2015-11-25 21:54:42 +01:00
|
|
|
|
|
|
|
if ($columns === null) {
|
|
|
|
$columns = $this->listImportedRowsetColumnNames($checksum);
|
|
|
|
} else {
|
|
|
|
$query->where('p.property_name IN (?)', $columns);
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = array();
|
|
|
|
$empty = (object) array();
|
|
|
|
foreach ($columns as $k => $v) {
|
2015-12-03 15:05:51 +01:00
|
|
|
$empty->$k = null;
|
2015-11-25 21:54:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($db->fetchAll($query) as $row) {
|
|
|
|
if (! array_key_exists($row->object_name, $result)) {
|
|
|
|
$result[$row->object_name] = clone($empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($row->format === 'json') {
|
|
|
|
$result[$row->object_name]->{$row->property_name} = json_decode($row->property_value);
|
|
|
|
} else {
|
|
|
|
$result[$row->object_name]->{$row->property_name} = $row->property_value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-18 13:43:15 +01:00
|
|
|
if ($filter) {
|
|
|
|
$filtered = array();
|
|
|
|
foreach ($result as $key => $row) {
|
|
|
|
if ($filter->matches($row)) {
|
|
|
|
$filtered[$key] = $row;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $filtered;
|
|
|
|
}
|
|
|
|
|
2015-11-25 21:54:42 +01:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2015-08-28 23:46:40 +02:00
|
|
|
public function getLatestImportedChecksum($source)
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
2016-03-15 17:48:37 +01:00
|
|
|
$lastRun = $db->select()->from(
|
|
|
|
array('r' => 'import_run'),
|
|
|
|
array('last_checksum' => $this->dbHexFunc('r.rowset_checksum'))
|
|
|
|
);
|
2015-08-28 23:46:40 +02:00
|
|
|
|
|
|
|
if (is_int($source) || ctype_digit($source)) {
|
|
|
|
$lastRun->where('source_id = ?', (int) $source);
|
|
|
|
} else {
|
|
|
|
$lastRun->where('source_name = ?', $source);
|
|
|
|
}
|
|
|
|
|
|
|
|
$lastRun->order('start_time DESC')->limit(1);
|
|
|
|
return $db->fetchOne($lastRun);
|
|
|
|
}
|
|
|
|
|
2015-12-18 09:05:04 +01:00
|
|
|
public function getObjectSummary()
|
|
|
|
{
|
|
|
|
$types = array(
|
|
|
|
'host',
|
|
|
|
'hostgroup',
|
|
|
|
'service',
|
|
|
|
'servicegroup',
|
|
|
|
'user',
|
|
|
|
'usergroup',
|
2016-02-17 17:21:36 +01:00
|
|
|
'command',
|
2015-12-18 09:05:04 +01:00
|
|
|
'timeperiod',
|
2016-03-12 02:05:26 +01:00
|
|
|
'notification',
|
2015-12-18 09:05:04 +01:00
|
|
|
'apiuser',
|
|
|
|
'endpoint',
|
|
|
|
'zone',
|
|
|
|
);
|
|
|
|
|
|
|
|
$queries = array();
|
|
|
|
$db = $this->db();
|
2016-02-27 11:37:29 +01:00
|
|
|
$cnt = "COALESCE(SUM(CASE WHEN o.object_type = '%s' THEN 1 ELSE 0 END), 0)";
|
|
|
|
|
2015-12-18 09:05:04 +01:00
|
|
|
foreach ($types as $type) {
|
|
|
|
$queries[] = $db->select()->from(
|
2016-02-02 17:42:09 +01:00
|
|
|
array('o' => 'icinga_' . $type),
|
2015-12-18 09:05:04 +01:00
|
|
|
array(
|
|
|
|
'icinga_type' => "('" . $type . "')",
|
2016-02-27 11:37:29 +01:00
|
|
|
'cnt_object' => sprintf($cnt, 'object'),
|
|
|
|
'cnt_template' => sprintf($cnt, 'template'),
|
|
|
|
'cnt_external' => sprintf($cnt, 'external_object'),
|
2015-12-18 09:05:04 +01:00
|
|
|
'cnt_total' => 'COUNT(*)',
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$query = $this->db()->select()->union($queries, Zend_Db_Select::SQL_UNION_ALL);
|
|
|
|
|
|
|
|
$result = array();
|
|
|
|
|
|
|
|
foreach ($db->fetchAll($query) as $row) {
|
|
|
|
$result[$row->icinga_type] = $row;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2015-07-22 23:33:24 +02:00
|
|
|
public function listImportedRowsetColumnNames($checksum)
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
|
|
|
|
$query = $db->select()->distinct()->from(
|
|
|
|
array('p' => 'imported_property'),
|
|
|
|
'property_name'
|
|
|
|
)->join(
|
|
|
|
array('rp' => 'imported_row_property'),
|
|
|
|
'rp.property_checksum = p.checksum',
|
|
|
|
array()
|
|
|
|
)->join(
|
|
|
|
array('rsr' => 'imported_rowset_row'),
|
|
|
|
'rsr.row_checksum = rp.row_checksum',
|
|
|
|
array()
|
2016-03-05 20:01:31 +01:00
|
|
|
)->where('rsr.rowset_checksum = ?', $this->quoteBinary(Util::hex2binary($checksum)));
|
2015-07-22 23:33:24 +02:00
|
|
|
|
|
|
|
return $db->fetchCol($query);
|
|
|
|
}
|
|
|
|
|
2015-06-01 16:30:24 +02:00
|
|
|
public function enumCommands()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaObjects('command');
|
2015-06-01 16:30:24 +02:00
|
|
|
}
|
|
|
|
|
2016-03-27 23:58:44 +02:00
|
|
|
public function enumTimeperiods()
|
|
|
|
{
|
|
|
|
return $this->enumIcingaObjects('timeperiod');
|
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumCheckcommands()
|
2015-04-24 14:26:44 +02:00
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
$filters = array(
|
|
|
|
'methods_execute IN (?)' => array('PluginCheck', 'IcingaCheck'),
|
|
|
|
|
|
|
|
);
|
|
|
|
return $this->enumIcingaObjects('command', $filters);
|
2015-06-08 14:37:02 +02:00
|
|
|
}
|
|
|
|
|
2016-03-11 09:07:22 +01:00
|
|
|
public function enumNotificationCommands()
|
|
|
|
{
|
|
|
|
$filters = array(
|
|
|
|
'methods_execute IN (?)' => array('PluginNotification'),
|
|
|
|
);
|
|
|
|
return $this->enumIcingaObjects('command', $filters);
|
|
|
|
}
|
|
|
|
|
2015-06-08 14:37:02 +02:00
|
|
|
public function getZoneName($id)
|
|
|
|
{
|
|
|
|
$objects = $this->enumZones();
|
|
|
|
return $objects[$id];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getCommandName($id)
|
|
|
|
{
|
|
|
|
$objects = $this->enumCommands();
|
|
|
|
return $objects[$id];
|
2015-04-24 14:26:44 +02:00
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumZones()
|
2015-04-24 14:26:44 +02:00
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaObjects('zone');
|
2015-04-24 14:26:44 +02:00
|
|
|
}
|
2015-06-02 17:29:07 +02:00
|
|
|
|
2015-12-02 21:31:38 +01:00
|
|
|
public function enumNonglobalZones()
|
|
|
|
{
|
|
|
|
$filters = array('is_global = ?' => 'n');
|
|
|
|
return $this->enumIcingaObjects('zone', $filters);
|
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumZoneTemplates()
|
2015-07-28 15:19:37 +02:00
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaTemplates('zone');
|
2015-07-28 15:19:37 +02:00
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumHosts()
|
2015-07-24 09:51:31 +02:00
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaObjects('host');
|
|
|
|
}
|
2015-07-24 09:51:31 +02:00
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumHostTemplates()
|
|
|
|
{
|
|
|
|
return $this->enumIcingaTemplates('host');
|
2015-07-24 09:51:31 +02:00
|
|
|
}
|
|
|
|
|
2015-06-02 17:29:07 +02:00
|
|
|
public function enumHostgroups()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaObjects('hostgroup');
|
2015-06-02 17:29:07 +02:00
|
|
|
}
|
2015-06-03 14:59:29 +02:00
|
|
|
|
|
|
|
public function enumServices()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaObjects('service');
|
2015-06-03 14:59:29 +02:00
|
|
|
}
|
|
|
|
|
2015-07-28 15:19:37 +02:00
|
|
|
public function enumServiceTemplates()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaTemplates('service');
|
2015-07-28 15:19:37 +02:00
|
|
|
}
|
|
|
|
|
2015-06-03 14:59:29 +02:00
|
|
|
public function enumServicegroups()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaObjects('servicegroup');
|
2015-06-03 14:59:29 +02:00
|
|
|
}
|
2015-06-08 14:37:02 +02:00
|
|
|
|
2015-06-12 13:16:41 +02:00
|
|
|
public function enumUsers()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enumIcingaObjects('user');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function enumUserTemplates()
|
|
|
|
{
|
|
|
|
return $this->enumIcingaTemplates('user');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function enumUsergroups()
|
|
|
|
{
|
|
|
|
return $this->enumIcingaObjects('usergroup');
|
|
|
|
}
|
|
|
|
|
2015-12-17 14:39:28 +01:00
|
|
|
public function enumApiUsers()
|
|
|
|
{
|
|
|
|
return $this->enumIcingaObjects('apiuser');
|
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumSyncRule()
|
|
|
|
{
|
|
|
|
return $this->enum('sync_rule', array('id', 'rule_name'));
|
2015-06-12 13:16:41 +02:00
|
|
|
}
|
|
|
|
|
2015-07-24 09:51:31 +02:00
|
|
|
public function enumImportSource()
|
|
|
|
{
|
2015-07-30 08:33:35 +02:00
|
|
|
return $this->enum('import_source', array('id', 'source_name'));
|
2015-07-24 09:51:31 +02:00
|
|
|
}
|
|
|
|
|
2015-07-28 11:49:30 +02:00
|
|
|
public function enumDatalist()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enum('director_datalist', array('id', 'list_name'));
|
2015-07-28 11:49:30 +02:00
|
|
|
}
|
|
|
|
|
2015-07-28 15:19:37 +02:00
|
|
|
public function enumDatafields()
|
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enum('director_datafield', array(
|
2015-07-28 15:19:37 +02:00
|
|
|
'id',
|
2015-07-29 18:07:21 +02:00
|
|
|
"caption || ' (' || varname || ')'",
|
|
|
|
));
|
2015-07-28 15:19:37 +02:00
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enum($table, $columns = null, $filters = array())
|
2015-06-12 13:16:41 +02:00
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
if ($columns === null) {
|
|
|
|
$columns = array('id', 'object_name');
|
|
|
|
}
|
|
|
|
|
|
|
|
$select = $this->db()->select()->from($table, $columns)->order($columns[1]);
|
|
|
|
foreach ($filters as $key => $val) {
|
|
|
|
$select->where($key, $val);
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:16:41 +02:00
|
|
|
return $this->db()->fetchPairs($select);
|
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumIcingaObjects($type, $filters = array())
|
2015-06-08 14:37:02 +02:00
|
|
|
{
|
2015-12-02 20:34:34 +01:00
|
|
|
$filters = array(
|
|
|
|
'object_type IN (?)' => array('object', 'external_object')
|
|
|
|
) + $filters;
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
return $this->enum('icinga_' . $type, null, $filters);
|
2015-06-08 14:37:02 +02:00
|
|
|
}
|
|
|
|
|
2015-07-29 18:07:21 +02:00
|
|
|
public function enumIcingaTemplates($type, $filters = array())
|
2015-06-08 14:37:02 +02:00
|
|
|
{
|
2015-07-29 18:07:21 +02:00
|
|
|
$filters = array('object_type = ?' => 'template') + $filters;
|
|
|
|
return $this->enum('icinga_' . $type, null, $filters);
|
2015-06-08 14:37:02 +02:00
|
|
|
}
|
2015-08-29 01:05:23 +02:00
|
|
|
|
2016-03-21 19:12:55 +01:00
|
|
|
public function listExternal($type)
|
|
|
|
{
|
|
|
|
$table = IcingaObject::createByType($type)->getTableName();
|
|
|
|
|
|
|
|
$select = $this->db()->select()->from(
|
|
|
|
array('o' => $table),
|
|
|
|
array('object_name' => 'o.object_name')
|
|
|
|
)->where(
|
|
|
|
'object_type = ?',
|
|
|
|
'external_object'
|
|
|
|
)->order('o.object_name');
|
|
|
|
|
|
|
|
$res = $this->db()->fetchCol($select);
|
2016-03-25 14:09:31 +01:00
|
|
|
if (empty($res)) {
|
|
|
|
return array();
|
|
|
|
}
|
2016-03-21 19:12:55 +01:00
|
|
|
|
|
|
|
return array_combine($res, $res);
|
|
|
|
}
|
|
|
|
|
2015-10-15 23:48:36 +02:00
|
|
|
public function fetchDistinctHostVars()
|
|
|
|
{
|
|
|
|
$select = $this->db()->select()->distinct()->from(
|
|
|
|
array('hv' => 'icinga_host_var'),
|
|
|
|
array(
|
|
|
|
'varname' => 'hv.varname',
|
|
|
|
'format' => 'hv.format',
|
|
|
|
'caption' => 'df.caption',
|
|
|
|
'datatype' => 'df.datatype'
|
|
|
|
)
|
|
|
|
)->joinLeft(
|
|
|
|
array('df' => 'director_datafield'),
|
|
|
|
'df.varname = hv.varname',
|
|
|
|
array()
|
|
|
|
)->order('varname');
|
|
|
|
|
|
|
|
return $this->db()->fetchAll($select);
|
|
|
|
}
|
|
|
|
|
2016-03-02 13:42:37 +01:00
|
|
|
public function isPgsql()
|
|
|
|
{
|
|
|
|
return $this->getDbType() === 'pgsql';
|
|
|
|
}
|
|
|
|
|
2016-03-05 20:01:31 +01:00
|
|
|
public function dbHexFunc($column)
|
2016-03-02 21:40:12 +01:00
|
|
|
{
|
|
|
|
if ($this->isPgsql()) {
|
|
|
|
return sprintf("LOWER(ENCODE(%s, 'hex'))", $column);
|
|
|
|
} else {
|
|
|
|
return sprintf("LOWER(HEX(%s))", $column);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-05 20:01:31 +01:00
|
|
|
public function quoteBinary($binary)
|
2016-03-02 21:54:38 +01:00
|
|
|
{
|
|
|
|
if ($this->isPgsql()) {
|
2016-03-05 20:01:31 +01:00
|
|
|
return new Zend_Db_Expr("'\\x" . bin2hex($binary) . "'");
|
2016-03-02 21:54:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $binary;
|
|
|
|
}
|
|
|
|
|
2016-05-02 10:45:04 +02:00
|
|
|
public function enumDeployedConfigs()
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
|
|
|
|
$columns = array(
|
|
|
|
'checksum' => $this->dbHexFunc('c.checksum'),
|
|
|
|
);
|
|
|
|
|
|
|
|
if ($this->isPgsql()) {
|
|
|
|
$columns['caption'] = 'SUBSTRING(' . $columns['checksum'] . ' FROM 1 FOR 7)';
|
|
|
|
} else {
|
|
|
|
$columns['caption'] = 'SUBSTRING(' . $columns['checksum'] . ', 1, 7)';
|
|
|
|
}
|
|
|
|
|
|
|
|
$query = $db->select()->from(
|
|
|
|
array('l' => 'director_deployment_log'),
|
|
|
|
$columns
|
|
|
|
)->joinLeft(
|
|
|
|
array('c' => 'director_generated_config'),
|
|
|
|
'c.checksum = l.config_checksum',
|
|
|
|
array()
|
|
|
|
)->order('l.start_time DESC');
|
|
|
|
|
|
|
|
return $db->fetchPairs($query);
|
|
|
|
}
|
|
|
|
|
2015-08-29 01:05:23 +02:00
|
|
|
public function getUncollectedDeployments()
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
|
|
|
|
$query = $db->select()
|
|
|
|
->from('director_deployment_log')
|
|
|
|
->where('stage_name IS NOT NULL')
|
|
|
|
->where('stage_collected IS NULL')
|
2015-09-29 18:53:53 +02:00
|
|
|
->where('startup_succeeded IS NULL')
|
2015-08-29 01:05:23 +02:00
|
|
|
->order('stage_name');
|
|
|
|
|
|
|
|
return DirectorDeploymentLog::loadAll($this, $query, 'stage_name');
|
|
|
|
}
|
2015-04-24 14:26:44 +02:00
|
|
|
}
|