[icinga-checkins] icinga.org: icingaweb2-module-director/feature-ddo-playground: Introduce ddo capture CLI command for importing host objects from the Icinga 2 API

git at icinga.org git at icinga.org
Tue Jul 19 10:31:53 CEST 2016


Module: icingaweb2-module-director
Branch: feature-ddo-playground
Commit: e3a52a32f8577d2a67eaa9aab20eeaad9ee563f8
URL:    https://git.icinga.org/?p=icingaweb2-module-director.git;a=commit;h=e3a52a32f8577d2a67eaa9aab20eeaad9ee563f8

Author: Eric Lippmann <eric.lippmann at netways.de>
Date:   Tue Jun 21 17:08:19 2016 +0200

Introduce ddo capture CLI command for importing host objects from the Icinga 2 API

---

 application/clicommands/DdoCommand.php |   90 +++++++++++++++++++
 library/Director/Ddo/HostObject.php    |  149 ++++++++++++++++++++++++++++++++
 library/Director/Ddo/schema.sql        |   34 ++++++++
 3 files changed, 273 insertions(+)

diff --git a/application/clicommands/DdoCommand.php b/application/clicommands/DdoCommand.php
new file mode 100644
index 0000000..4a2643a
--- /dev/null
+++ b/application/clicommands/DdoCommand.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Icinga\Module\Director\Clicommands;
+
+use Icinga\Application\Logger;
+use Icinga\Data\ConfigObject;
+use Icinga\Module\Director\Cli\Command;
+use Icinga\Module\Director\Ddo\DdoDb;
+use Icinga\Module\Director\Ddo\HostObject;
+
+class DdoCommand extends Command
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function init()
+    {
+        // Force stderr log writer. Too bad that we can't use our Logger as instance
+        Logger::create(new ConfigObject(array(
+            'log'  => 'stderr',
+            'level' => 'debug'
+        )));
+    }
+
+    /**
+     * Get the connection to the DDO database
+     *
+     * @return \Icinga\Module\Director\Ddo\DdoDb
+     */
+    public function getDb()
+    {
+        return DdoDb::fromResourceName('ddo');
+    }
+
+    public function captureAction()
+    {
+        $sleepSeconds = 60;
+
+        $api = $this->api();
+        /** @var \Icinga\Module\Director\Core\CoreApi $api */
+
+        $db = $this->getDb();
+
+        $ddoHosts = HostObject::loadAll($db, null, 'checksum');
+        $ddoHostsCount = count($ddoHosts);
+
+        while (true) {
+            $union = array();
+            $unionCount = 0;
+
+            $apiHosts = $api->getObjects(null, 'hosts');
+
+            foreach ($apiHosts as $name => $apiHost) {
+                $ddoHost = HostObject::fromApiObject($name, $apiHost, $db);
+
+                if (isset($ddoHosts[$ddoHost->checksum])) {
+                    $ddoHost->merge($ddoHosts[$ddoHost->checksum]);
+
+                    $union[$ddoHost->checksum] = null;
+                    ++$unionCount;
+                }
+
+                if ($ddoHost->hasBeenModified()) {
+                    if (! $ddoHost->hasBeenLoadedFromDb()) {
+                        $ddoHosts[$ddoHost->checksum] = $ddoHost;
+                        ++$ddoHostsCount;
+                        ++$unionCount;
+                    }
+                    Logger::debug('Updating host object %s', $name);
+                    $ddoHost->store();
+                }
+            }
+
+            if ($ddoHostsCount !== $unionCount) {
+                $diff = array_diff_key($ddoHosts, $union);
+                foreach ($diff as $checksum => $ddoHost) {
+                    Logger::debug('Deleting host object %s', $ddoHost->name);
+                    /** @var HostObject $ddoHost */
+                    $ddoHost->delete();
+                    unset($ddoHosts[$checksum]);
+                }
+                $ddoHostsCount = count($ddoHosts);
+            }
+
+            Logger::debug('Sleeping %u seconds', $sleepSeconds);
+
+            sleep($sleepSeconds);
+        }
+    }
+}
diff --git a/library/Director/Ddo/HostObject.php b/library/Director/Ddo/HostObject.php
new file mode 100644
index 0000000..19770c9
--- /dev/null
+++ b/library/Director/Ddo/HostObject.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace Icinga\Module\Director\Ddo;
+
+use Icinga\Data\Db\DbConnection;
+
+// TODO(el): Respect ctime and mtime columns w/o influencing the hasBeenModified magic
+
+/**
+ * A DDO host object
+ */
+class HostObject extends DdoObject
+{
+    /**
+     * {@inheritdoc}
+     */
+//    protected $timestamps = array('ctime', 'mtime');
+
+    /**
+     * {@inheritdoc}
+     */
+    protected $table = 'ddo_host';
+
+    /**
+     * {@inheritdoc}
+     */
+    protected $keyName = 'checksum';
+
+    /**
+     * {@inheritdoc}
+     */
+    protected $defaultProperties = array(
+        'checksum'                  => null,
+        'name'                      => null,
+        'name_ci'                   => null,
+        'label'                     => null,
+        'action_url'                => null,
+        'notes_url'                 => null,
+        'address'                   => null,
+        'address6'                  => null,
+        'address_bin'               => null,
+        'address6_bin'              => null,
+        'active_checks_enabled'     => null,
+        'event_handler_enabled'     => null,
+        'flapping_enabled'          => null,
+        'notifications_enabled'     => null,
+        'passive_checks_enabled'    => null,
+        'perfdata_enabled'          => null,
+        'check_command'             => null,
+        'check_interval'            => null,
+        'check_retry_interval'      => null
+    );
+
+    /**
+     * Create a DDO host object from an Icinga 2 API host object
+     *
+     * @param   string          $name       The name of the object
+     * @param   object          $apiObject  The API object record
+     * @param   DbConnection    $connection The connection to the DDO database
+     *
+     * @return  static
+     */
+    public static function fromApiObject($name, $apiObject, DbConnection $connection = null)
+    {
+        $properties = array(
+            'checksum'                  => hex2bin(sha1($name)),
+            'name'                      => $name,
+            'name_ci'                   => $name,
+            'label'                     => $apiObject->attrs->display_name,
+            'action_url'                => $apiObject->attrs->action_url,
+            'notes_url'                 => $apiObject->attrs->notes_url,
+            'address'                   => $apiObject->attrs->address,
+            'address6'                  => $apiObject->attrs->address6,
+            'address_bin'               => $apiObject->attrs->address,
+            'address6_bin'              => $apiObject->attrs->address6,
+            'active_checks_enabled'     => $apiObject->attrs->enable_active_checks,
+            'event_handler_enabled'     => $apiObject->attrs->enable_event_handler,
+            'flapping_enabled'          => $apiObject->attrs->enable_flapping,
+            'notifications_enabled'     => $apiObject->attrs->enable_notifications,
+            'passive_checks_enabled'    => $apiObject->attrs->enable_passive_checks,
+            'perfdata_enabled'          => $apiObject->attrs->enable_perfdata,
+            'check_command'             => $apiObject->attrs->check_command,
+            'check_interval'            => $apiObject->attrs->check_interval,
+            'check_retry_interval'      => $apiObject->attrs->retry_interval,
+        );
+
+        return static::create($properties, $connection);
+    }
+
+    /**
+     * {@inheritdoc}
+     * Interpret properties ending w/ _enabled as boolean
+     */
+    public function propertyIsBoolean($property)
+    {
+        if (substr($property, -8) === '_enabled') {
+            return true;
+        }
+        return parent::propertyIsBoolean($property);
+    }
+
+    public function getAddressBin()
+    {
+        $value = $this->properties['address_bin'];
+        if ($value !== null) {
+            $value = inet_ntop($value);
+        }
+
+        return $value;
+    }
+
+    public function setAddressBin($address)
+    {
+        if (! empty($address)) {
+            $value = @inet_pton($address);
+            if ($value === false) {
+                $value = null;
+            }
+        } else {
+            $value = null;
+        }
+        return $this->reallySet('address_bin', $value);
+    }
+
+    public function getAddress6Bin()
+    {
+        $value = $this->properties['address6_bin'];
+        if ($value !== null) {
+            $value = inet_ntop($value);
+        }
+
+        return $value;
+    }
+
+    public function setAddress6Bin($address6)
+    {
+        if (! empty($address6)) {
+            $value = @inet_pton($address6);
+            if ($value === false) {
+                $value = null;
+            }
+        } else {
+            $value = null;
+        }
+
+        return $this->reallySet('address6_bin', $value);
+    }
+}
+
diff --git a/library/Director/Ddo/schema.sql b/library/Director/Ddo/schema.sql
new file mode 100644
index 0000000..97c66a9
--- /dev/null
+++ b/library/Director/Ddo/schema.sql
@@ -0,0 +1,34 @@
+DROP TABLE IF EXISTS ddo_host;
+CREATE TABLE ddo_host (
+  checksum VARBINARY(20) NOT NULL,
+
+  name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  name_ci VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  label VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+
+  action_url VARCHAR(2083),
+  notes_url VARCHAR(2083),
+
+  address VARCHAR(255),
+  address6 VARCHAR(255),
+  address_bin BINARY(4),
+  address6_bin BINARY(16),
+
+  active_checks_enabled ENUM('y', 'n'),
+  event_handler_enabled ENUM('y', 'n'),
+  flapping_enabled ENUM('y', 'n'),
+  notifications_enabled ENUM('y', 'n'),
+  passive_checks_enabled ENUM('y', 'n'),
+  perfdata_enabled ENUM('y', 'n'),
+
+  check_command VARCHAR(255),
+  check_interval INT(10) UNSIGNED,
+  check_retry_interval INT(10) UNSIGNED,
+
+--  ctime BIGINT NOT NULL,
+--  mtime BIGINT NOT NULL,
+
+  UNIQUE KEY idx_host_checksum (checksum),
+  UNIQUE KEY idx_host_name (name),
+  INDEX idx_host_name_ci (name_ci)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;



More information about the icinga-checkins mailing list