mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-24 22:24:44 +02:00
IcingaDB: Start keeping track of Host/Service to Dependency relationship
This does not work in this state! Trying to refresh Dependency if a Host or Service being member of this Dependency has a state change.
This commit is contained in:
parent
8714f72d65
commit
ef93f945a2
@ -19,6 +19,7 @@
|
||||
#include "icinga/command.hpp"
|
||||
#include "icinga/compatutility.hpp"
|
||||
#include "icinga/customvarobject.hpp"
|
||||
#include "icinga/dependency.hpp"
|
||||
#include "icinga/host.hpp"
|
||||
#include "icinga/service.hpp"
|
||||
#include "icinga/hostgroup.hpp"
|
||||
@ -61,6 +62,7 @@ std::vector<Type::Ptr> IcingaDB::GetTypes()
|
||||
// Then sync them for similar reasons.
|
||||
Downtime::TypeInstance,
|
||||
Comment::TypeInstance,
|
||||
Dependency::TypeInstance,
|
||||
|
||||
HostGroup::TypeInstance,
|
||||
ServiceGroup::TypeInstance,
|
||||
@ -791,6 +793,137 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == Dependency::TypeInstance) {
|
||||
auto& dependencyNodes (hMSets[m_PrefixConfigObject + "dependency:node"]);
|
||||
auto& dependencyEdges (hMSets[m_PrefixConfigObject + "dependency:edge"]);
|
||||
auto& redundancyGroups (hMSets[m_PrefixConfigObject + "redundancygroup"]);
|
||||
|
||||
Dependency::Ptr dependency = static_pointer_cast<Dependency>(object);
|
||||
|
||||
Host::Ptr parentHost, childHost;
|
||||
Service::Ptr parentService, childService;
|
||||
tie(parentHost, parentService) = GetHostService(dependency->GetParent());
|
||||
tie(childHost, childService) = GetHostService(dependency->GetChild());
|
||||
String redundancyGroup = dependency->GetRedundancyGroup();
|
||||
|
||||
String redundancyGroupId, dependencyNodeParentId, dependencyNodeChildId, dependencyNodeReduId;
|
||||
|
||||
Dictionary::Ptr parentNodeData, childNodeData;
|
||||
|
||||
if (parentService) {
|
||||
dependencyNodeParentId = HashValue(new Array({
|
||||
m_EnvironmentId,
|
||||
GetObjectIdentifier(parentHost),
|
||||
GetObjectIdentifier(parentService)}));
|
||||
parentNodeData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"host_id", GetObjectIdentifier(parentHost)},
|
||||
{"service_id", GetObjectIdentifier(parentService)}});
|
||||
|
||||
m_CheckablesToDependencies->Set(GetObjectIdentifier(parentService), dependency);
|
||||
} else {
|
||||
dependencyNodeParentId = HashValue(new Array({
|
||||
m_EnvironmentId,
|
||||
GetObjectIdentifier(parentHost)}));
|
||||
parentNodeData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"host_id", GetObjectIdentifier(parentHost)}});
|
||||
|
||||
m_CheckablesToDependencies->Set(GetObjectIdentifier(parentHost), dependency);
|
||||
}
|
||||
|
||||
if (childService) {
|
||||
dependencyNodeChildId = HashValue(new Array({
|
||||
m_EnvironmentId,
|
||||
GetObjectIdentifier(childHost),
|
||||
GetObjectIdentifier(childService)}));
|
||||
childNodeData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"host_id", GetObjectIdentifier(childHost)},
|
||||
{"service_id", GetObjectIdentifier(childService)}});
|
||||
|
||||
m_CheckablesToDependencies->Set(GetObjectIdentifier(childService), dependency);
|
||||
} else {
|
||||
dependencyNodeChildId = HashValue(new Array({
|
||||
m_EnvironmentId,
|
||||
GetObjectIdentifier(childHost)}));
|
||||
childNodeData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"host_id", GetObjectIdentifier(childHost)}});
|
||||
|
||||
m_CheckablesToDependencies->Set(GetObjectIdentifier(childHost), dependency);
|
||||
}
|
||||
|
||||
dependencyNodes.emplace_back(dependencyNodeParentId);
|
||||
dependencyNodes.emplace_back(JsonEncode(parentNodeData));
|
||||
dependencyNodes.emplace_back(dependencyNodeChildId);
|
||||
dependencyNodes.emplace_back(JsonEncode(childNodeData));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, dependencyNodeParentId, m_PrefixConfigObject + "dependency:node", parentNodeData);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, dependencyNodeChildId, m_PrefixConfigObject + "dependency:node", childNodeData);
|
||||
}
|
||||
|
||||
if (!redundancyGroup.IsEmpty()) {
|
||||
/* TODO: name should be suffixed with names of all children.
|
||||
* however, at this point I don't have this information,
|
||||
* only the direct neighbors.
|
||||
*/
|
||||
redundancyGroupId = HashValue(new Array({m_EnvironmentId, redundancyGroup, dependencyNodeChildId}));
|
||||
dependencyNodeReduId = redundancyGroupId;
|
||||
|
||||
redundancyGroups.emplace_back(redundancyGroupId);
|
||||
Dictionary::Ptr groupData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"name", redundancyGroupId},
|
||||
{"display_name", redundancyGroup}});
|
||||
redundancyGroups.emplace_back(JsonEncode(groupData));
|
||||
|
||||
dependencyNodes.emplace_back(dependencyNodeReduId);
|
||||
Dictionary::Ptr reduNodeData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"redundancy_group_id", redundancyGroupId}});
|
||||
dependencyNodes.emplace_back(JsonEncode(reduNodeData));
|
||||
|
||||
String edgeInId = HashValue(new Array({m_EnvironmentId, dependencyNodeChildId, dependencyNodeReduId}));
|
||||
dependencyEdges.emplace_back(edgeInId);
|
||||
Dictionary::Ptr edgeInData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"from_node_id", dependencyNodeChildId},
|
||||
{"to_node_id", dependencyNodeReduId}});
|
||||
dependencyEdges.emplace_back(JsonEncode(edgeInData));
|
||||
|
||||
String edgeOutId = HashValue(new Array({m_EnvironmentId, dependencyNodeReduId, dependencyNodeParentId}));
|
||||
dependencyEdges.emplace_back(edgeOutId);
|
||||
Dictionary::Ptr edgeOutData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"from_node_id", dependencyNodeReduId},
|
||||
{"to_node_id", dependencyNodeParentId},
|
||||
{"dependency_id", GetObjectIdentifier(dependency)}});
|
||||
dependencyEdges.emplace_back(JsonEncode(edgeOutData));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, redundancyGroupId, m_PrefixConfigObject + "redundancygroup", groupData);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, dependencyNodeReduId, m_PrefixConfigObject + "dependency:node", reduNodeData);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, edgeInId, m_PrefixConfigObject + "dependency:edge", edgeInData);
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, edgeOutId, m_PrefixConfigObject + "dependency:edge", edgeOutData);
|
||||
}
|
||||
} else {
|
||||
String edgeId = HashValue(new Array({m_EnvironmentId, dependencyNodeChildId, dependencyNodeParentId}));
|
||||
dependencyEdges.emplace_back(edgeId);
|
||||
Dictionary::Ptr edgeData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"from_node_id", dependencyNodeChildId},
|
||||
{"to_node_id", dependencyNodeParentId},
|
||||
{"dependency_id", GetObjectIdentifier(dependency)}});
|
||||
dependencyEdges.emplace_back(JsonEncode(edgeData));
|
||||
|
||||
if (runtimeUpdate) {
|
||||
AddObjectDataToRuntimeUpdates(runtimeUpdates, edgeId, m_PrefixConfigObject + "dependency:edge", edgeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == TimePeriod::TypeInstance) {
|
||||
TimePeriod::Ptr timeperiod = static_pointer_cast<TimePeriod>(object);
|
||||
|
||||
@ -1121,6 +1254,47 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
|
||||
}
|
||||
}
|
||||
|
||||
void IcingaDB::UpdateDependencyState(const Dependency::Ptr& dependency)
|
||||
{
|
||||
if (!m_Rcon || !m_Rcon->IsConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& redundancyGroupStates (hMSets[m_PrefixConfigObject + "redundancygroup:state"]);
|
||||
|
||||
String redundancyGroup = dependency->GetRedundancyGroup();
|
||||
|
||||
if (!redundancyGroup.IsEmpty()) {
|
||||
Host::Ptr childHost;
|
||||
Service::Ptr childService;
|
||||
tie(childHost, childService) = GetHostService(dependency->GetChild());
|
||||
|
||||
String dependencyNodeChildId = HashValue(
|
||||
(childService)
|
||||
? new Array({ m_EnvironmentId, GetObjectIdentifier(childHost), GetObjectIdentifier(childService) })
|
||||
: new Array({ m_EnvironmentId, GetObjectIdentifier(childHost) }));
|
||||
String redundancyGroupId = HashValue(new Array({
|
||||
m_EnvironmentId,
|
||||
redundancyGroup,
|
||||
dependencyNodeChildId}));
|
||||
|
||||
redundancyGroupStates.emplace_back(redundancyGroupId);
|
||||
Dictionary::Ptr groupStateData = new Dictionary({
|
||||
{"environment_id", m_EnvironmentId},
|
||||
{"redundancy_group_id", redundancyGroupId},
|
||||
{"failed", !((childService) ? childService->IsReachable() : childHost->IsReachable())},
|
||||
{"last_state_change", TimestampToMilliseconds(Utility::GetTime())}});
|
||||
redundancyGroupStates.emplace_back(JsonEncode(groupStateData));
|
||||
|
||||
// TODO
|
||||
// AddObjectDataToRuntimeUpdates(runtimeUpdates, redundancyGroupId, m_PrefixConfigObject + "redundancygroup:state", groupStateData);
|
||||
// dataClone->Set("id", objectKey); // redundancyGroupId
|
||||
// dataClone->Set("redis_key", redisKey); // m_PrefixConfigObject + "redundancygroup:state"
|
||||
// dataClone->Set("runtime_type", "upsert");
|
||||
// runtimeUpdates.emplace_back(dataClone);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the state information of a checkable in Redis.
|
||||
*
|
||||
@ -1450,6 +1624,32 @@ bool IcingaDB::PrepareObject(const ConfigObject::Ptr& object, Dictionary::Ptr& a
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == Dependency::TypeInstance) {
|
||||
Dependency::Ptr dependency = static_pointer_cast<Dependency>(object);
|
||||
String redundancyGroup = dependency->GetRedundancyGroup();
|
||||
|
||||
attributes->Set("name", GetObjectIdentifier(dependency));
|
||||
|
||||
if (!redundancyGroup.IsEmpty()) {
|
||||
Host::Ptr childHost;
|
||||
Service::Ptr childService;
|
||||
tie(childHost, childService) = GetHostService(dependency->GetChild());
|
||||
|
||||
String dependencyNodeChildId = HashValue(
|
||||
(childService)
|
||||
? new Array({ m_EnvironmentId, GetObjectIdentifier(childHost), GetObjectIdentifier(childService) })
|
||||
: new Array({ m_EnvironmentId, GetObjectIdentifier(childHost) }));
|
||||
String redundancyGroupId = HashValue(new Array({
|
||||
m_EnvironmentId,
|
||||
redundancyGroup,
|
||||
dependencyNodeChildId}));
|
||||
|
||||
attributes->Set("redundancy_group_id", redundancyGroupId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == Downtime::TypeInstance) {
|
||||
Downtime::Ptr downtime = static_pointer_cast<Downtime>(object);
|
||||
|
||||
|
@ -38,6 +38,8 @@ IcingaDB::IcingaDB()
|
||||
|
||||
m_PrefixConfigObject = "icinga:";
|
||||
m_PrefixConfigCheckSum = "icinga:checksum:";
|
||||
|
||||
m_CheckablesToDependencies = new Dictionary();
|
||||
}
|
||||
|
||||
void IcingaDB::Validate(int types, const ValidationUtils& utils)
|
||||
|
@ -103,6 +103,7 @@ private:
|
||||
std::vector<String> GetTypeDumpSignalKeys(const Type::Ptr& type);
|
||||
void InsertObjectDependencies(const ConfigObject::Ptr& object, const String typeName, std::map<String, std::vector<String>>& hMSets,
|
||||
std::vector<Dictionary::Ptr>& runtimeUpdates, bool runtimeUpdate);
|
||||
void UpdateDependencyState(const Dependency::Ptr& dependency);
|
||||
void UpdateState(const Checkable::Ptr& checkable, StateUpdate mode);
|
||||
void SendConfigUpdate(const ConfigObject::Ptr& object, bool runtimeUpdate);
|
||||
void CreateConfigUpdate(const ConfigObject::Ptr& object, const String type, std::map<String, std::vector<String>>& hMSets,
|
||||
@ -224,6 +225,8 @@ private:
|
||||
std::unordered_map<ConfigType*, RedisConnection::Ptr> m_Rcons;
|
||||
std::atomic_size_t m_PendingRcons;
|
||||
|
||||
Dictionary::Ptr m_CheckablesToDependencies;
|
||||
|
||||
struct {
|
||||
DumpedGlobals CustomVar, ActionUrl, NotesUrl, IconImage;
|
||||
} m_DumpedGlobals;
|
||||
|
Loading…
x
Reference in New Issue
Block a user