DB IDO: Dump custom attributes as json encoded arrays/dictionaries; add 'is_json' column

refs #7560
This commit is contained in:
Michael Friedrich 2014-11-04 12:18:07 +01:00
parent 6cafce5d7e
commit 58d5c42d9c
9 changed files with 78 additions and 10 deletions

View File

@ -62,6 +62,8 @@ Icinga 2 is available as [Vagrant Demo VM](#vagrant).
* DB IDO schema update to version `1.12.0` * DB IDO schema update to version `1.12.0`
* schema files in `lib/db_ido_{mysql,pgsql}/schema` (source) * schema files in `lib/db_ido_{mysql,pgsql}/schema` (source)
* Table `programstatus`: New column `program_version`
* Table `customvariables` and `customvariablestatus`: New column `is_json` (required for custom attribute array/dictionary support)
* New CLI commands #7245 * New CLI commands #7245
* `icinga2 feature {enable,disable}` replaces `icinga2-{enable,disable}-feature` script #7250 * `icinga2 feature {enable,disable}` replaces `icinga2-{enable,disable}-feature` script #7250
* `icinga2 object list` replaces `icinga2-list-objects` script #7251 * `icinga2 object list` replaces `icinga2-list-objects` script #7251

View File

@ -186,6 +186,7 @@ New columns:
{host,service}group | notes | TEXT | NULL | - {host,service}group | notes | TEXT | NULL | -
{host,service}group | notes_url | TEXT | NULL | - {host,service}group | notes_url | TEXT | NULL | -
{host,service}group | action_url | TEXT | NULL | - {host,service}group | action_url | TEXT | NULL | -
customvariable* | is_json | integer | 0 | Defines whether `varvalue` is a json encoded string from custom attributes, or not
Additional command custom variables populated from 'vars' dictionary. Additional command custom variables populated from 'vars' dictionary.
Additional global custom variables populated from 'Vars' constant (object_id is NULL). Additional global custom variables populated from 'Vars' constant (object_id is NULL).
@ -654,5 +655,3 @@ Not supported: `neb_callbacks`, `neb_callbacks_rate`, `requests`, `requests_rate
current_host_ | join | Prefix for attributes from implicit join with hosts table. current_host_ | join | Prefix for attributes from implicit join with hosts table.
Not supported: `debug_info`. Not supported: `debug_info`.

View File

@ -26,6 +26,7 @@
#include "remote/endpoint.hpp" #include "remote/endpoint.hpp"
#include "base/dynamicobject.hpp" #include "base/dynamicobject.hpp"
#include "base/dynamictype.hpp" #include "base/dynamictype.hpp"
#include "base/json.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
@ -171,10 +172,12 @@ void DbObject::SendVarsConfigUpdate(void)
continue; continue;
String value; String value;
int is_json = 0;
if (kv.second.IsObjectType<Array>()) if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>()) {
value = Utility::Join(kv.second, ';'); value = JsonEncode(kv.second);
else is_json = 1;
} else
value = kv.second; value = kv.second;
int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0; int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0;
@ -186,6 +189,7 @@ void DbObject::SendVarsConfigUpdate(void)
Dictionary::Ptr fields = make_shared<Dictionary>(); Dictionary::Ptr fields = make_shared<Dictionary>();
fields->Set("varname", kv.first); fields->Set("varname", kv.first);
fields->Set("varvalue", value); fields->Set("varvalue", value);
fields->Set("is_json", is_json);
fields->Set("config_type", 1); fields->Set("config_type", 1);
fields->Set("has_been_modified", overridden); fields->Set("has_been_modified", overridden);
fields->Set("object_id", obj); fields->Set("object_id", obj);
@ -219,9 +223,18 @@ void DbObject::SendVarsStatusUpdate(void)
ObjectLock olock (vars); ObjectLock olock (vars);
BOOST_FOREACH(const Dictionary::Pair& kv, vars) { BOOST_FOREACH(const Dictionary::Pair& kv, vars) {
if (kv.first.IsEmpty() || kv.second.IsObject()) if (kv.first.IsEmpty())
continue; continue;
String value;
int is_json = 0;
if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>()) {
value = JsonEncode(kv.second);
is_json = 1;
} else
value = kv.second;
int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0; int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0;
Log(LogDebug, "DbObject") Log(LogDebug, "DbObject")
@ -229,8 +242,9 @@ void DbObject::SendVarsStatusUpdate(void)
<< "' overridden: " << overridden; << "' overridden: " << overridden;
Dictionary::Ptr fields = make_shared<Dictionary>(); Dictionary::Ptr fields = make_shared<Dictionary>();
fields->Set("varname", Convert::ToString(kv.first)); fields->Set("varname", kv.first);
fields->Set("varvalue", Convert::ToString(kv.second)); fields->Set("varvalue", value);
fields->Set("is_json", is_json);
fields->Set("has_been_modified", overridden); fields->Set("has_been_modified", overridden);
fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime())); fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
fields->Set("object_id", obj); fields->Set("object_id", obj);

View File

@ -93,11 +93,12 @@ void UserDbObject::OnConfigUpdate(void)
if (vars) { /* This is sparta. */ if (vars) { /* This is sparta. */
for (int i = 1; i <= 6; i++) { for (int i = 1; i <= 6; i++) {
String key = "address" + Convert::ToString(i); String key = "address" + Convert::ToString(i);
String val = vars->Get(key);
if (val.IsEmpty()) if (!vars->Contains(key))
continue; continue;
String val = vars->Get(key);
fields->Set("contact_id", DbValue::FromObjectInsertID(user)); fields->Set("contact_id", DbValue::FromObjectInsertID(user));
fields->Set("address_number", i); fields->Set("address_number", i);
fields->Set("address", val); fields->Set("address", val);

View File

@ -339,6 +339,7 @@ CREATE TABLE IF NOT EXISTS icinga_customvariables (
has_been_modified smallint default 0, has_been_modified smallint default 0,
varname varchar(255) character set latin1 collate latin1_general_cs default NULL, varname varchar(255) character set latin1 collate latin1_general_cs default NULL,
varvalue TEXT character set latin1 default '', varvalue TEXT character set latin1 default '',
is_json smallint default 0,
PRIMARY KEY (customvariable_id), PRIMARY KEY (customvariable_id),
UNIQUE KEY object_id_2 (object_id,config_type,varname), UNIQUE KEY object_id_2 (object_id,config_type,varname),
KEY varname (varname) KEY varname (varname)
@ -358,6 +359,7 @@ CREATE TABLE IF NOT EXISTS icinga_customvariablestatus (
has_been_modified smallint default 0, has_been_modified smallint default 0,
varname varchar(255) character set latin1 collate latin1_general_cs default NULL, varname varchar(255) character set latin1 collate latin1_general_cs default NULL,
varvalue TEXT character set latin1 default '', varvalue TEXT character set latin1 default '',
is_json smallint default 0,
PRIMARY KEY (customvariablestatus_id), PRIMARY KEY (customvariablestatus_id),
UNIQUE KEY object_id_2 (object_id,varname), UNIQUE KEY object_id_2 (object_id,varname),
KEY varname (varname) KEY varname (varname)

View File

@ -12,6 +12,9 @@ ALTER TABLE `icinga_programstatus` ADD COLUMN `program_version` varchar(64) char
ALTER TABLE icinga_contacts MODIFY alias TEXT character set latin1 default ''; ALTER TABLE icinga_contacts MODIFY alias TEXT character set latin1 default '';
ALTER TABLE icinga_hosts MODIFY alias TEXT character set latin1 default ''; ALTER TABLE icinga_hosts MODIFY alias TEXT character set latin1 default '';
ALTER TABLE icinga_customvariables ADD COLUMN is_json smallint default 0;
ALTER TABLE icinga_customvariablestatus ADD COLUMN is_json smallint default 0;
-- ----------------------------------------- -- -----------------------------------------
-- update dbversion -- update dbversion
-- ----------------------------------------- -- -----------------------------------------

View File

@ -365,6 +365,7 @@ CREATE TABLE icinga_customvariables (
has_been_modified INTEGER default 0, has_been_modified INTEGER default 0,
varname TEXT default '', varname TEXT default '',
varvalue TEXT default '', varvalue TEXT default '',
is_json INTEGER default 0,
CONSTRAINT PK_customvariable_id PRIMARY KEY (customvariable_id) , CONSTRAINT PK_customvariable_id PRIMARY KEY (customvariable_id) ,
CONSTRAINT UQ_customvariables UNIQUE (object_id,config_type,varname) CONSTRAINT UQ_customvariables UNIQUE (object_id,config_type,varname)
) ; ) ;
@ -384,6 +385,7 @@ CREATE TABLE icinga_customvariablestatus (
has_been_modified INTEGER default 0, has_been_modified INTEGER default 0,
varname TEXT default '', varname TEXT default '',
varvalue TEXT default '', varvalue TEXT default '',
is_json INTEGER default 0,
CONSTRAINT PK_customvariablestatus_id PRIMARY KEY (customvariablestatus_id) , CONSTRAINT PK_customvariablestatus_id PRIMARY KEY (customvariablestatus_id) ,
CONSTRAINT UQ_customvariablestatus UNIQUE (object_id,varname) CONSTRAINT UQ_customvariablestatus UNIQUE (object_id,varname)
) ; ) ;

View File

@ -9,6 +9,10 @@
ALTER TABLE icinga_programstatus ADD COLUMN program_version TEXT default NULL; ALTER TABLE icinga_programstatus ADD COLUMN program_version TEXT default NULL;
ALTER TABLE icinga_customvariables ADD COLUMN is_json INTEGER default 0;
ALTER TABLE icinga_customvariablestatus ADD COLUMN is_json INTEGER default 0;
-- ----------------------------------------- -- -----------------------------------------
-- update dbversion -- update dbversion
-- ----------------------------------------- -- -----------------------------------------

41
test/config/7560.conf Normal file
View File

@ -0,0 +1,41 @@
object Host "7560-server" {
import "test-generic-host"
address = "127.0.0.1"
check_command = "hostalive"
vars.interfaces += {
eth0 = {
port = 1
vlan = "internal"
address = "127.0.0.2"
qos = "enabled"
}
eth1 = {
port = 2
vlan = "mgmt"
address = "127.0.1.2"
}
eth2 = {
port = 3
vlan = "remote"
address = "127.0.2.2"
}
}
}
apply Service "if-" for (if_name => config in host.vars.interfaces) {
import "test-generic-service"
check_command = "ping4"
vars.qos = "disabled"
vars += config
display_name = "if-" + if_name + "-" + vars.vlan
notes = "Interface check for Port " + string(vars.port) + " in VLAN " + vars.vlan + " on Address " + vars.address + " QoS " + vars.qos
notes_url = "http://foreman.company.com/hosts/" + host.name
action_url = "http://snmp.checker.company.com/" + host.name + "if-" + if_name
assign where match("7560-*", host.name) && typeof(host.vars.interfaces) == typeof({})
}