mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-27 15:44:11 +02:00
cluster: Implement authority checks.
This commit is contained in:
parent
8a1293f750
commit
95909d82fe
@ -106,6 +106,11 @@ void CheckerComponent::CheckThreadProc(void)
|
|||||||
bool forced = service->GetForceNextCheck();
|
bool forced = service->GetForceNextCheck();
|
||||||
bool check = true;
|
bool check = true;
|
||||||
|
|
||||||
|
if (!service->HasAuthority("checker")) {
|
||||||
|
Log(LogDebug, "checker", "Skipping check for service '" + service->GetName() + "': not authoritative");
|
||||||
|
check = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!forced) {
|
if (!forced) {
|
||||||
if (!service->GetEnableActiveChecks()) {
|
if (!service->GetEnableActiveChecks()) {
|
||||||
Log(LogDebug, "checker", "Skipping check for service '" + service->GetName() + "': active checks are disabled");
|
Log(LogDebug, "checker", "Skipping check for service '" + service->GetName() + "': active checks are disabled");
|
||||||
|
@ -85,6 +85,8 @@ void ClusterComponent::Start(void)
|
|||||||
Service::OnAcknowledgementSet.connect(boost::bind(&ClusterComponent::AcknowledgementSetHandler, this, _1, _2, _3, _4, _5, _6));
|
Service::OnAcknowledgementSet.connect(boost::bind(&ClusterComponent::AcknowledgementSetHandler, this, _1, _2, _3, _4, _5, _6));
|
||||||
Service::OnAcknowledgementCleared.connect(boost::bind(&ClusterComponent::AcknowledgementClearedHandler, this, _1, _2));
|
Service::OnAcknowledgementCleared.connect(boost::bind(&ClusterComponent::AcknowledgementClearedHandler, this, _1, _2));
|
||||||
|
|
||||||
|
DynamicObject::OnCheckAuthority.connect(boost::bind(&ClusterComponent::CheckAuthorityHandler, this, _1, _2, _3));
|
||||||
|
|
||||||
Endpoint::OnMessageReceived.connect(boost::bind(&ClusterComponent::MessageHandler, this, _1, _2));
|
Endpoint::OnMessageReceived.connect(boost::bind(&ClusterComponent::MessageHandler, this, _1, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,6 +1121,48 @@ void ClusterComponent::MessageHandler(const Endpoint::Ptr& sender, const Diction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClusterComponent::CheckAuthorityHandler(const DynamicObject::Ptr& object, const String& type, bool& result)
|
||||||
|
{
|
||||||
|
Array::Ptr authorities = object->GetAuthorities();
|
||||||
|
std::vector<String> endpoints;
|
||||||
|
|
||||||
|
if ((type == "checker" && DynamicType::GetByName("CheckerComponent")) ||
|
||||||
|
(type == "notification" && DynamicType::GetByName("NotificationComponent")))
|
||||||
|
endpoints.push_back(GetIdentity());
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjects<Endpoint>()) {
|
||||||
|
bool match = false;
|
||||||
|
|
||||||
|
if (!endpoint->IsConnected())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (authorities) {
|
||||||
|
BOOST_FOREACH(const String& authority, authorities) {
|
||||||
|
if (Utility::Match(authority, endpoint->GetName())) {
|
||||||
|
match = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
endpoints.push_back(endpoint->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(endpoints.begin(), endpoints.end());
|
||||||
|
|
||||||
|
String key = object->GetType()->GetName() + "\t" + object->GetName();
|
||||||
|
unsigned long hash = Utility::SDBM(key);
|
||||||
|
unsigned long index = hash % endpoints.size();
|
||||||
|
|
||||||
|
Log(LogDebug, "cluster", "Authority for object '" + object->GetName() + "' of type '" + object->GetType()->GetName() + "' is '" + endpoints[index] + "'.");
|
||||||
|
|
||||||
|
result = (endpoints[index] == GetIdentity());
|
||||||
|
}
|
||||||
|
|
||||||
void ClusterComponent::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const
|
void ClusterComponent::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const
|
||||||
{
|
{
|
||||||
DynamicObject::InternalSerialize(bag, attributeTypes);
|
DynamicObject::InternalSerialize(bag, attributeTypes);
|
||||||
|
@ -111,6 +111,7 @@ private:
|
|||||||
void AcknowledgementSetHandler(const Service::Ptr& service, const String& author, const String& comment, AcknowledgementType type, double expiry, const String& authority);
|
void AcknowledgementSetHandler(const Service::Ptr& service, const String& author, const String& comment, AcknowledgementType type, double expiry, const String& authority);
|
||||||
void AcknowledgementClearedHandler(const Service::Ptr& service, const String& authority);
|
void AcknowledgementClearedHandler(const Service::Ptr& service, const String& authority);
|
||||||
void MessageHandler(const Endpoint::Ptr& sender, const Dictionary::Ptr& message);
|
void MessageHandler(const Endpoint::Ptr& sender, const Dictionary::Ptr& message);
|
||||||
|
void CheckAuthorityHandler(const DynamicObject::Ptr& object, const String& type, bool& result);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -168,6 +168,26 @@ void Endpoint::SetRemoteLogPosition(double ts)
|
|||||||
m_RemoteLogPosition = ts;
|
m_RemoteLogPosition = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr Endpoint::GetFeatures(void) const
|
||||||
|
{
|
||||||
|
return m_Features;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Endpoint::SetFeatures(const Dictionary::Ptr& features)
|
||||||
|
{
|
||||||
|
m_Features = features;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Endpoint::HasFeature(const String& type) const
|
||||||
|
{
|
||||||
|
Dictionary::Ptr features = GetFeatures();
|
||||||
|
|
||||||
|
if (!features)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return features->Get(type);
|
||||||
|
}
|
||||||
|
|
||||||
void Endpoint::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const
|
void Endpoint::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const
|
||||||
{
|
{
|
||||||
DynamicObject::InternalSerialize(bag, attributeTypes);
|
DynamicObject::InternalSerialize(bag, attributeTypes);
|
||||||
@ -183,6 +203,7 @@ void Endpoint::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes)
|
|||||||
bag->Set("seen", m_Seen);
|
bag->Set("seen", m_Seen);
|
||||||
bag->Set("local_log_position", m_LocalLogPosition);
|
bag->Set("local_log_position", m_LocalLogPosition);
|
||||||
bag->Set("remote_log_position", m_RemoteLogPosition);
|
bag->Set("remote_log_position", m_RemoteLogPosition);
|
||||||
|
bag->Set("features", m_Features);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,5 +222,6 @@ void Endpoint::InternalDeserialize(const Dictionary::Ptr& bag, int attributeType
|
|||||||
m_Seen = bag->Get("seen");
|
m_Seen = bag->Get("seen");
|
||||||
m_LocalLogPosition = bag->Get("local_log_position");
|
m_LocalLogPosition = bag->Get("local_log_position");
|
||||||
m_RemoteLogPosition = bag->Get("remote_log_position");
|
m_RemoteLogPosition = bag->Get("remote_log_position");
|
||||||
|
m_Features = bag->Get("features");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,11 @@ public:
|
|||||||
double GetRemoteLogPosition(void) const;
|
double GetRemoteLogPosition(void) const;
|
||||||
void SetRemoteLogPosition(double ts);
|
void SetRemoteLogPosition(double ts);
|
||||||
|
|
||||||
|
Dictionary::Ptr GetFeatures(void) const;
|
||||||
|
void SetFeatures(const Dictionary::Ptr& features);
|
||||||
|
|
||||||
|
bool HasFeature(const String& type) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const;
|
virtual void InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const;
|
||||||
virtual void InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes);
|
virtual void InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes);
|
||||||
@ -80,6 +85,7 @@ private:
|
|||||||
double m_Seen;
|
double m_Seen;
|
||||||
double m_LocalLogPosition;
|
double m_LocalLogPosition;
|
||||||
double m_RemoteLogPosition;
|
double m_RemoteLogPosition;
|
||||||
|
Dictionary::Ptr m_Features;
|
||||||
|
|
||||||
void MessageThreadProc(const Stream::Ptr& stream);
|
void MessageThreadProc(const Stream::Ptr& stream);
|
||||||
};
|
};
|
||||||
|
@ -41,6 +41,7 @@ using namespace icinga;
|
|||||||
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStarted;
|
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStarted;
|
||||||
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStopped;
|
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStopped;
|
||||||
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStateChanged;
|
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStateChanged;
|
||||||
|
boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool&)> DynamicObject::OnCheckAuthority;
|
||||||
|
|
||||||
DynamicObject::DynamicObject(void)
|
DynamicObject::DynamicObject(void)
|
||||||
: m_Active(false)
|
: m_Active(false)
|
||||||
@ -82,6 +83,7 @@ void DynamicObject::InternalSerialize(const Dictionary::Ptr& bag, int attributeT
|
|||||||
bag->Set("__type", m_Type);
|
bag->Set("__type", m_Type);
|
||||||
bag->Set("methods", m_Methods);
|
bag->Set("methods", m_Methods);
|
||||||
bag->Set("custom", m_Custom);
|
bag->Set("custom", m_Custom);
|
||||||
|
bag->Set("authorities", m_Authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
bag->Set("extensions", m_Extensions);
|
bag->Set("extensions", m_Extensions);
|
||||||
@ -98,6 +100,7 @@ void DynamicObject::InternalDeserialize(const Dictionary::Ptr& bag, int attribut
|
|||||||
m_Type = bag->Get("__type");
|
m_Type = bag->Get("__type");
|
||||||
m_Methods = bag->Get("methods");
|
m_Methods = bag->Get("methods");
|
||||||
m_Custom = bag->Get("custom");
|
m_Custom = bag->Get("custom");
|
||||||
|
m_Authorities = bag->Get("authorities");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Extensions = bag->Get("extensions");
|
m_Extensions = bag->Get("extensions");
|
||||||
@ -118,6 +121,18 @@ bool DynamicObject::IsActive(void) const
|
|||||||
return m_Active;
|
return m_Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array::Ptr DynamicObject::GetAuthorities(void) const
|
||||||
|
{
|
||||||
|
return m_Authorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynamicObject::HasAuthority(const String& type)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
OnCheckAuthority(GetSelf(), type, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void DynamicObject::SetExtension(const String& key, const Object::Ptr& object)
|
void DynamicObject::SetExtension(const String& key, const Object::Ptr& object)
|
||||||
{
|
{
|
||||||
Dictionary::Ptr extensions = m_Extensions;
|
Dictionary::Ptr extensions = m_Extensions;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "base/i2-base.h"
|
#include "base/i2-base.h"
|
||||||
#include "base/object.h"
|
#include "base/object.h"
|
||||||
#include "base/dictionary.h"
|
#include "base/dictionary.h"
|
||||||
|
#include "base/array.h"
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -62,6 +63,7 @@ public:
|
|||||||
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStarted;
|
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStarted;
|
||||||
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStopped;
|
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStopped;
|
||||||
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStateChanged;
|
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStateChanged;
|
||||||
|
static boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool&)> OnCheckAuthority;
|
||||||
|
|
||||||
Value InvokeMethod(const String& method, const std::vector<Value>& arguments);
|
Value InvokeMethod(const String& method, const std::vector<Value>& arguments);
|
||||||
|
|
||||||
@ -70,6 +72,9 @@ public:
|
|||||||
|
|
||||||
bool IsActive(void) const;
|
bool IsActive(void) const;
|
||||||
|
|
||||||
|
Array::Ptr GetAuthorities(void) const;
|
||||||
|
bool HasAuthority(const String& type);
|
||||||
|
|
||||||
void SetExtension(const String& key, const Object::Ptr& object);
|
void SetExtension(const String& key, const Object::Ptr& object);
|
||||||
Object::Ptr GetExtension(const String& key);
|
Object::Ptr GetExtension(const String& key);
|
||||||
void ClearExtension(const String& key);
|
void ClearExtension(const String& key);
|
||||||
@ -111,6 +116,7 @@ private:
|
|||||||
Dictionary::Ptr m_Extensions;
|
Dictionary::Ptr m_Extensions;
|
||||||
Dictionary::Ptr m_Methods;
|
Dictionary::Ptr m_Methods;
|
||||||
Dictionary::Ptr m_Custom;
|
Dictionary::Ptr m_Custom;
|
||||||
|
Array::Ptr m_Authorities;
|
||||||
|
|
||||||
bool m_Active;
|
bool m_Active;
|
||||||
|
|
||||||
|
@ -551,3 +551,15 @@ String Utility::GetThreadName(void)
|
|||||||
|
|
||||||
return *name;
|
return *name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long Utility::SDBM(const String& str)
|
||||||
|
{
|
||||||
|
unsigned long hash = 0;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
BOOST_FOREACH(char c, str) {
|
||||||
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
@ -95,6 +95,8 @@ public:
|
|||||||
static void SetThreadName(const String& name, bool os = true);
|
static void SetThreadName(const String& name, bool os = true);
|
||||||
static String GetThreadName(void);
|
static String GetThreadName(void);
|
||||||
|
|
||||||
|
static unsigned long SDBM(const String& str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utility(void);
|
Utility(void);
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@ type DynamicObject {
|
|||||||
|
|
||||||
%attribute dictionary "custom" {
|
%attribute dictionary "custom" {
|
||||||
%attribute string "*"
|
%attribute string "*"
|
||||||
|
},
|
||||||
|
|
||||||
|
%attribute array "authorities" {
|
||||||
|
%attribute string "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user