diff --git a/Makefile.am b/Makefile.am
index ac6bea37f..bf5f101b0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,7 @@
## Created by Anjuta
SUBDIRS = ltdl \
+ mmatch \
base \
cJSON \
jsonrpc \
diff --git a/base/base.vcxproj b/base/base.vcxproj
index 50b13abfa..19037d4f6 100644
--- a/base/base.vcxproj
+++ b/base/base.vcxproj
@@ -93,7 +93,12 @@
-
+
+ $(SolutionDir)\mmatch;$(IncludePath)
+
+
+ $(SolutionDir)\mmatch;$(IncludePath)
+
diff --git a/base/configcollection.cpp b/base/configcollection.cpp
index a4c0d640d..585e0b47f 100644
--- a/base/configcollection.cpp
+++ b/base/configcollection.cpp
@@ -38,14 +38,7 @@ void ConfigCollection::AddObject(const ConfigObject::Ptr& object)
RemoveObject(object);
Objects[object->GetName()] = object;
-
- EventArgs ea;
- ea.Source = object;
- OnObjectCreated(ea);
-
- ConfigHive::Ptr hive = m_Hive.lock();
- if (hive)
- hive->OnObjectCreated(ea);
+ object->Commit();
}
/**
diff --git a/base/configcollection.h b/base/configcollection.h
index 6dc1a66ba..989672de9 100644
--- a/base/configcollection.h
+++ b/base/configcollection.h
@@ -28,9 +28,8 @@ public:
void ForEachObject(function callback);
- Event OnObjectCreated;
+ Event OnObjectCommitted;
Event OnObjectRemoved;
- Event OnPropertyChanged;
};
}
diff --git a/base/confighive.h b/base/confighive.h
index 52701ebfe..b0c89ddef 100644
--- a/base/confighive.h
+++ b/base/confighive.h
@@ -23,9 +23,8 @@ public:
void ForEachObject(const string& type,
function callback);
- Event OnObjectCreated;
+ Event OnObjectCommitted;
Event OnObjectRemoved;
- Event OnPropertyChanged;
};
}
diff --git a/base/configobject.cpp b/base/configobject.cpp
index c0dfbe96e..e34e32520 100644
--- a/base/configobject.cpp
+++ b/base/configobject.cpp
@@ -30,7 +30,6 @@ void ConfigObject::SetHive(const ConfigHive::WeakPtr& hive)
throw InvalidArgumentException("Config object already has a parent hive.");
m_Hive = hive;
- OnPropertyChanged += bind_weak(&ConfigObject::PropertyChangedHandler, shared_from_this());
}
/**
@@ -118,21 +117,19 @@ bool ConfigObject::GetReplicated(void) const
}
/**
- * PropertyChangedHandler
+ * Commit
*
* Handles changed properties by propagating them to the hive
* and collection this object is contained in.
*
- * @param dpcea The event arguments.
- * @returns 0.
*/
-int ConfigObject::PropertyChangedHandler(const PropertyChangedEventArgs& dpcea)
+void ConfigObject::Commit(void)
{
ConfigHive::Ptr hive = m_Hive.lock();
if (hive) {
- hive->GetCollection(m_Type)->OnPropertyChanged(dpcea);
- hive->OnPropertyChanged(dpcea);
+ EventArgs ea;
+ ea.Source = shared_from_this();
+ hive->GetCollection(m_Type)->OnObjectCommitted(ea);
+ hive->OnObjectCommitted(ea);
}
-
- return 0;
}
diff --git a/base/configobject.h b/base/configobject.h
index 1caee2eb3..b8aae2a10 100644
--- a/base/configobject.h
+++ b/base/configobject.h
@@ -17,8 +17,6 @@ private:
string m_Type;
bool m_Replicated;
- int PropertyChangedHandler(const PropertyChangedEventArgs& dpcea);
-
public:
typedef shared_ptr Ptr;
typedef weak_ptr WeakPtr;
@@ -36,6 +34,8 @@ public:
void SetReplicated(bool replicated);
bool GetReplicated(void) const;
+
+ void Commit(void);
};
}
diff --git a/base/utility.cpp b/base/utility.cpp
index 4136f81f0..a2a8111f7 100644
--- a/base/utility.cpp
+++ b/base/utility.cpp
@@ -1,4 +1,5 @@
#include "i2-base.h"
+#include
using namespace icinga;
@@ -137,3 +138,8 @@ shared_ptr Utility::GetX509Certificate(string pemfile)
return shared_ptr(cert, X509_free);
}
+
+bool Utility::Match(string pattern, string text)
+{
+ return (match(pattern.c_str(), text.c_str()) != 0);
+}
diff --git a/base/utility.h b/base/utility.h
index ef95d885f..715722b5a 100644
--- a/base/utility.h
+++ b/base/utility.h
@@ -47,6 +47,8 @@ public:
static shared_ptr MakeSSLContext(string pubkey, string privkey, string cakey);
static string GetCertificateCN(const shared_ptr& certificate);
static shared_ptr GetX509Certificate(string pemfile);
+
+ static bool Match(string pattern, string text);
};
}
diff --git a/components/configfile/configfilecomponent.cpp b/components/configfile/configfilecomponent.cpp
index 4406e6e8c..c95004824 100644
--- a/components/configfile/configfilecomponent.cpp
+++ b/components/configfile/configfilecomponent.cpp
@@ -55,13 +55,23 @@ void ConfigFileComponent::Start(void)
for (cJSON *property = object->child; property != NULL; property = property->next) {
string key = property->string;
+
+ if (property->type == cJSON_String) {
+ string value = property->valuestring;
- if (property->type != cJSON_String)
- continue;
+ cfgobj->SetPropertyString(key, value);
+ } else if (property->type == cJSON_Array) {
+ Dictionary::Ptr items = make_shared();
- string value = property->valuestring;
+ for (cJSON *item = property->child; item != NULL; item = item->next) {
+ if (item->type != cJSON_String)
+ continue;
- cfgobj->SetPropertyString(key, value);
+ items->AddUnnamedPropertyString(item->valuestring);
+ }
+
+ cfgobj->SetPropertyDictionary(key, items);
+ }
}
GetApplication()->GetConfigHive()->AddObject(cfgobj);
diff --git a/components/configrpc/configrpccomponent.cpp b/components/configrpc/configrpccomponent.cpp
index 20a3fccfe..1d67c6300 100644
--- a/components/configrpc/configrpccomponent.cpp
+++ b/components/configrpc/configrpccomponent.cpp
@@ -19,24 +19,20 @@ void ConfigRpcComponent::Start(void)
m_ConfigRpcEndpoint->RegisterMethodHandler("config::FetchObjects",
bind_weak(&ConfigRpcComponent::FetchObjectsHandler, shared_from_this()));
- configHive->OnObjectCreated += bind_weak(&ConfigRpcComponent::LocalObjectCreatedHandler, shared_from_this());
+ configHive->OnObjectCommitted += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this());
configHive->OnObjectRemoved += bind_weak(&ConfigRpcComponent::LocalObjectRemovedHandler, shared_from_this());
- configHive->OnPropertyChanged += bind_weak(&ConfigRpcComponent::LocalPropertyChangedHandler, shared_from_this());
- m_ConfigRpcEndpoint->RegisterMethodSource("config::ObjectCreated");
+ m_ConfigRpcEndpoint->RegisterMethodSource("config::ObjectCommitted");
m_ConfigRpcEndpoint->RegisterMethodSource("config::ObjectRemoved");
- m_ConfigRpcEndpoint->RegisterMethodSource("config::PropertyChanged");
}
endpointManager->OnNewEndpoint += bind_weak(&ConfigRpcComponent::NewEndpointHandler, shared_from_this());
m_ConfigRpcEndpoint->RegisterMethodSource("config::FetchObjects");
- m_ConfigRpcEndpoint->RegisterMethodHandler("config::ObjectCreated",
- bind_weak(&ConfigRpcComponent::RemoteObjectUpdatedHandler, shared_from_this()));
+ m_ConfigRpcEndpoint->RegisterMethodHandler("config::ObjectCommitted",
+ bind_weak(&ConfigRpcComponent::RemoteObjectCommittedHandler, shared_from_this()));
m_ConfigRpcEndpoint->RegisterMethodHandler("config::ObjectRemoved",
bind_weak(&ConfigRpcComponent::RemoteObjectRemovedHandler, shared_from_this()));
- m_ConfigRpcEndpoint->RegisterMethodHandler("config::PropertyChanged",
- bind_weak(&ConfigRpcComponent::RemoteObjectUpdatedHandler, shared_from_this()));
endpointManager->RegisterEndpoint(m_ConfigRpcEndpoint);
}
@@ -115,7 +111,7 @@ int ConfigRpcComponent::FetchObjectsHandler(const NewRequestEventArgs& ea)
return 0;
}
-int ConfigRpcComponent::LocalObjectCreatedHandler(const EventArgs& ea)
+int ConfigRpcComponent::LocalObjectCommittedHandler(const EventArgs& ea)
{
ConfigObject::Ptr object = static_pointer_cast(ea.Source);
@@ -141,32 +137,7 @@ int ConfigRpcComponent::LocalObjectRemovedHandler(const EventArgs& ea)
return 0;
}
-int ConfigRpcComponent::LocalPropertyChangedHandler(const PropertyChangedEventArgs& ea)
-{
- ConfigObject::Ptr object = static_pointer_cast(ea.Source);
-
- if (!ShouldReplicateObject(object))
- return 0;
-
- JsonRpcRequest msg = MakeObjectMessage(object, "config::PropertyChanged", false);
- Message params;
- msg.SetParams(params);
-
- Message properties;
- params.GetDictionary()->SetPropertyDictionary("properties", properties.GetDictionary());
-
- string value;
- if (!object->GetPropertyString(ea.Property, &value))
- return 0;
-
- properties.GetDictionary()->SetPropertyString(ea.Property, value);
-
- GetEndpointManager()->SendMulticastRequest(m_ConfigRpcEndpoint, msg);
-
- return 0;
-}
-
-int ConfigRpcComponent::RemoteObjectUpdatedHandler(const NewRequestEventArgs& ea)
+int ConfigRpcComponent::RemoteObjectCommittedHandler(const NewRequestEventArgs& ea)
{
JsonRpcRequest message = ea.Request;
bool was_null = false;
diff --git a/components/configrpc/configrpccomponent.h b/components/configrpc/configrpccomponent.h
index 27ce4bb3b..cdc4d8d96 100644
--- a/components/configrpc/configrpccomponent.h
+++ b/components/configrpc/configrpccomponent.h
@@ -12,12 +12,11 @@ private:
int NewEndpointHandler(const NewEndpointEventArgs& ea);
int SessionEstablishedHandler(const EventArgs& ea);
- int LocalObjectCreatedHandler(const EventArgs& ea);
+ int LocalObjectCommittedHandler(const EventArgs& ea);
int LocalObjectRemovedHandler(const EventArgs& ea);
- int LocalPropertyChangedHandler(const PropertyChangedEventArgs& ea);
int FetchObjectsHandler(const NewRequestEventArgs& ea);
- int RemoteObjectUpdatedHandler(const NewRequestEventArgs& ea);
+ int RemoteObjectCommittedHandler(const NewRequestEventArgs& ea);
int RemoteObjectRemovedHandler(const NewRequestEventArgs& ea);
static JsonRpcRequest MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties);
diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp
index 4717f47bb..7dcb34053 100644
--- a/components/discovery/discoverycomponent.cpp
+++ b/components/discovery/discoverycomponent.cpp
@@ -27,15 +27,16 @@ void DiscoveryComponent::Start(void)
GetConfig()->GetPropertyInteger("broker", &isBroker);
m_Broker = (isBroker != 0);
- if (IsBroker()) {
- m_DiscoveryEndpoint->RegisterMethodSource("discovery::NewComponent");
- m_DiscoveryEndpoint->RegisterMethodHandler("discovery::RegisterComponent",
- bind_weak(&DiscoveryComponent::RegisterComponentMessageHandler, shared_from_this()));
- }
-
m_DiscoveryEndpoint->RegisterMethodSource("discovery::RegisterComponent");
+ m_DiscoveryEndpoint->RegisterMethodHandler("discovery::RegisterComponent",
+ bind_weak(&DiscoveryComponent::RegisterComponentMessageHandler, shared_from_this()));
+
+ if (IsBroker())
+ m_DiscoveryEndpoint->RegisterMethodSource("discovery::NewComponent");
+
m_DiscoveryEndpoint->RegisterMethodHandler("discovery::NewComponent",
bind_weak(&DiscoveryComponent::NewComponentMessageHandler, shared_from_this()));
+
m_DiscoveryEndpoint->RegisterMethodHandler("discovery::Welcome",
bind_weak(&DiscoveryComponent::WelcomeMessageHandler, shared_from_this()));
@@ -49,6 +50,9 @@ void DiscoveryComponent::Start(void)
m_DiscoveryTimer->SetInterval(30);
m_DiscoveryTimer->OnTimerExpired += bind_weak(&DiscoveryComponent::DiscoveryTimerHandler, shared_from_this());
m_DiscoveryTimer->Start();
+
+ /* call the timer as soon as possible */
+ m_DiscoveryTimer->Reschedule(0);
}
/**
@@ -104,10 +108,8 @@ int DiscoveryComponent::NewEndpointHandler(const NewEndpointEventArgs& neea)
{
neea.Endpoint->OnIdentityChanged += bind_weak(&DiscoveryComponent::NewIdentityHandler, shared_from_this());
- if (IsBroker()) {
- /* accept discovery::RegisterComponent messages from any endpoint */
- neea.Endpoint->RegisterMethodSource("discovery::RegisterComponent");
- }
+ /* accept discovery::RegisterComponent messages from any endpoint */
+ neea.Endpoint->RegisterMethodSource("discovery::RegisterComponent");
/* accept discovery::Welcome messages from any endpoint */
neea.Endpoint->RegisterMethodSource("discovery::Welcome");
@@ -231,12 +233,6 @@ int DiscoveryComponent::NewIdentityHandler(const EventArgs& ea)
GetEndpointManager()->ForEachEndpoint(bind(&DiscoveryComponent::CheckExistingEndpoint, this, endpoint, _1));
- ConfigCollection::Ptr brokerCollection = GetApplication()->GetConfigHive()->GetCollection("broker");
- if (brokerCollection->GetObject(identity)) {
- /* accept discovery::NewComponent messages from brokers */
- endpoint->RegisterMethodSource("discovery::NewComponent");
- }
-
// we assume the other component _always_ wants
// discovery::RegisterComponent messages from us
endpoint->RegisterMethodSink("discovery::RegisterComponent");
@@ -394,6 +390,30 @@ void DiscoveryComponent::SendDiscoveryMessage(string method, string identity, En
GetEndpointManager()->SendMulticastRequest(m_DiscoveryEndpoint, request);
}
+bool DiscoveryComponent::HasMessagePermission(Dictionary::Ptr roles, string messageType, string message)
+{
+ ConfigHive::Ptr configHive = GetApplication()->GetConfigHive();
+ ConfigCollection::Ptr roleCollection = configHive->GetCollection("role");
+
+ for (DictionaryIterator ip = roles->Begin(); ip != roles->End(); ip++) {
+ ConfigObject::Ptr role = roleCollection->GetObject(ip->second);
+
+ if (!role)
+ continue;
+
+ Dictionary::Ptr permissions;
+ if (!role->GetPropertyDictionary(messageType, &permissions))
+ continue;
+
+ for (DictionaryIterator is = permissions->Begin(); is != permissions->End(); is++) {
+ if (Utility::Match(is->second.GetString(), message))
+ return true;
+ }
+ }
+
+ return false;
+}
+
/**
* ProcessDiscoveryMessage
*
@@ -402,8 +422,9 @@ void DiscoveryComponent::SendDiscoveryMessage(string method, string identity, En
*
* @param identity The authorative identity of the component.
* @param message The discovery message.
+ * @param trusted Whether the message comes from a trusted source (i.e. a broker).
*/
-void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessage message)
+void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessage message, bool trusted)
{
/* ignore discovery messages that are about ourselves */
if (identity == GetEndpointManager()->GetIdentity())
@@ -416,14 +437,20 @@ void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessa
message.GetNode(&info->Node);
message.GetService(&info->Service);
+ ConfigHive::Ptr configHive = GetApplication()->GetConfigHive();
+ ConfigCollection::Ptr endpointCollection = configHive->GetCollection("endpoint");
+
+ ConfigObject::Ptr endpointConfig = endpointCollection->GetObject(identity);
+ Dictionary::Ptr roles;
+ if (endpointConfig)
+ endpointConfig->GetPropertyDictionary("roles", &roles);
+
Message provides;
if (message.GetProvides(&provides)) {
DictionaryIterator i;
for (i = provides.GetDictionary()->Begin(); i != provides.GetDictionary()->End(); i++) {
- if (IsBroker()) {
- /* TODO: Add authorisation checks here */
- }
- info->PublishedMethods.insert(i->second);
+ if (trusted || HasMessagePermission(roles, "publish", i->second))
+ info->PublishedMethods.insert(i->second);
}
}
@@ -431,16 +458,14 @@ void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessa
if (message.GetSubscribes(&subscribes)) {
DictionaryIterator i;
for (i = subscribes.GetDictionary()->Begin(); i != subscribes.GetDictionary()->End(); i++) {
- if (IsBroker()) {
- /* TODO: Add authorisation checks here */
- }
- info->SubscribedMethods.insert(i->second);
+ if (trusted || HasMessagePermission(roles, "subscribe", i->second))
+ info->SubscribedMethods.insert(i->second);
}
}
map::iterator i;
- i = m_Components.find(identity);
+ i = m_Components.find(identity);
if (i != m_Components.end())
m_Components.erase(i);
@@ -472,7 +497,7 @@ int DiscoveryComponent::NewComponentMessageHandler(const NewRequestEventArgs& nr
if (!message.GetIdentity(&identity))
return 0;
- ProcessDiscoveryMessage(identity, message);
+ ProcessDiscoveryMessage(identity, message, true);
return 0;
}
@@ -486,45 +511,36 @@ int DiscoveryComponent::NewComponentMessageHandler(const NewRequestEventArgs& nr
*/
int DiscoveryComponent::RegisterComponentMessageHandler(const NewRequestEventArgs& nrea)
{
- /* ignore discovery::RegisterComponent messages when we're not a broker */
- if (!IsBroker())
- return 0;
-
DiscoveryMessage message;
nrea.Request.GetParams(&message);
- ProcessDiscoveryMessage(nrea.Sender->GetIdentity(), message);
+ ProcessDiscoveryMessage(nrea.Sender->GetIdentity(), message, false);
return 0;
}
/**
- * BrokerConfigHandler
+ * EndpointConfigHandler
*
- * Processes "broker" config objects.
+ * Processes "endpoint" config objects.
*
* @param ea Event arguments for the new config object.
* @returns 0
*/
-int DiscoveryComponent::BrokerConfigHandler(const EventArgs& ea)
+int DiscoveryComponent::EndpointConfigHandler(const EventArgs& ea)
{
ConfigObject::Ptr object = static_pointer_cast(ea.Source);
EndpointManager::Ptr endpointManager = GetEndpointManager();
- /* Check if we're already connected to this broker. */
+ /* Check if we're already connected to this endpoint. */
if (endpointManager->GetEndpointByIdentity(object->GetName()))
return 0;
- string node;
- if (!object->GetPropertyString("node", &node))
- throw InvalidArgumentException("'node' property required for 'broker' config object.");
-
- string service;
- if (!object->GetPropertyString("service", &service))
- throw InvalidArgumentException("'service' property required for 'broker' config object.");
-
- /* reconnect to this broker */
- endpointManager->AddConnection(node, service);
+ string node, service;
+ if (object->GetPropertyString("node", &node) && object->GetPropertyString("service", &service)) {
+ /* reconnect to this endpoint */
+ endpointManager->AddConnection(node, service);
+ }
return 0;
}
@@ -545,9 +561,9 @@ int DiscoveryComponent::DiscoveryTimerHandler(const TimerEventArgs& tea)
time_t now;
time(&now);
- /* check whether we have to reconnect to one of our upstream brokers */
- ConfigCollection::Ptr brokerCollection = GetApplication()->GetConfigHive()->GetCollection("broker");
- brokerCollection->ForEachObject(bind(&DiscoveryComponent::BrokerConfigHandler, this, _1));
+ /* check whether we have to reconnect to one of our upstream endpoints */
+ ConfigCollection::Ptr endpointCollection = GetApplication()->GetConfigHive()->GetCollection("endpoint");
+ endpointCollection->ForEachObject(bind(&DiscoveryComponent::EndpointConfigHandler, this, _1));
map::iterator i;
for (i = m_Components.begin(); i != m_Components.end(); ) {
diff --git a/components/discovery/discoverycomponent.h b/components/discovery/discoverycomponent.h
index a00b90bff..77535ebad 100644
--- a/components/discovery/discoverycomponent.h
+++ b/components/discovery/discoverycomponent.h
@@ -36,7 +36,7 @@ private:
int WelcomeMessageHandler(const NewRequestEventArgs& nrea);
void SendDiscoveryMessage(string method, string identity, Endpoint::Ptr recipient);
- void ProcessDiscoveryMessage(string identity, DiscoveryMessage message);
+ void ProcessDiscoveryMessage(string identity, DiscoveryMessage message, bool trusted);
bool GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const;
@@ -51,7 +51,9 @@ private:
void FinishDiscoverySetup(Endpoint::Ptr endpoint);
- int BrokerConfigHandler(const EventArgs& ea);
+ int EndpointConfigHandler(const EventArgs& ea);
+
+ bool HasMessagePermission(Dictionary::Ptr roles, string messageType, string message);
static const int RegistrationTTL = 300;
diff --git a/configure.ac b/configure.ac
index 2f3c619d8..c5b681897 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,5 +56,5 @@ components/discovery/Makefile
icinga/Makefile
icinga-app/Makefile
jsonrpc/Makefile
-
+mmatch/Makefile
])
diff --git a/icinga-app/icinga1.conf b/icinga-app/icinga1.conf
index 17d963f91..601ab601f 100644
--- a/icinga-app/icinga1.conf
+++ b/icinga-app/icinga1.conf
@@ -5,7 +5,7 @@
"privkey": "icinga-c1.key",
"pubkey": "icinga-c1.crt",
"cakey": "ca.crt",
- "node": "10.0.10.3",
+ "node": "10.0.10.14",
"service": "7777"
}
},
@@ -16,5 +16,8 @@
},
"host": {
"localhost": { "node": "127.0.0.1" }
+ },
+ "include": {
+ "permissions.conf": { "test": [ "hello", "world" ] }
}
}
\ No newline at end of file
diff --git a/icinga-app/icinga2.conf b/icinga-app/icinga2.conf
index 46d84d8e0..c457b86da 100644
--- a/icinga-app/icinga2.conf
+++ b/icinga-app/icinga2.conf
@@ -14,7 +14,21 @@
"demo": { "replicate": "0" },
"discovery": { "replicate": "0", "broker": "0" }
},
- "broker": {
- "icinga-c1": { "replicate": "0", "node": "10.0.10.3", "service": "7777" }
+ "endpoint": {
+ "icinga-c1": {
+ "replicate": "0",
+ "node": "10.0.10.14",
+ "service": "7777",
+ "roles": [ "broker", "demo" ]
+ }
+ },
+ "role": {
+ "broker": {
+ "publish": [ "discovery::NewComponent" ]
+ },
+ "demo": {
+ "publish": [ "demo::*" ],
+ "subscribe": [ "demo::*" ]
+ }
}
}
\ No newline at end of file
diff --git a/icinga-app/icinga3.conf b/icinga-app/icinga3.conf
index ed9894d89..c6af61273 100644
--- a/icinga-app/icinga3.conf
+++ b/icinga-app/icinga3.conf
@@ -14,7 +14,21 @@
"demo": { "replicate": "0" },
"discovery": { "replicate": "0", "broker": "0" }
},
- "broker": {
- "icinga-c1": { "replicate": "0", "node": "10.0.10.3", "service": "7777" }
+ "endpoint": {
+ "icinga-c1": {
+ "replicate": "0",
+ "node": "10.0.10.14",
+ "service": "7777",
+ "roles": [ "broker", "demo" ]
+ }
+ },
+ "role": {
+ "broker": {
+ "publish": [ "discovery::NewComponent" ]
+ },
+ "demo": {
+ "publish": [ "demo::*" ],
+ "subscribe": [ "demo::*" ]
+ }
}
}
\ No newline at end of file
diff --git a/icinga.sln b/icinga.sln
index e5f25da2f..21ee272ee 100644
--- a/icinga.sln
+++ b/icinga.sln
@@ -2,6 +2,9 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "base\base.vcxproj", "{9C92DA90-FD53-43A9-A244-90F2E8AF9677}"
+ ProjectSection(ProjectDependencies) = postProject
+ {19CBCE06-3F5C-479A-BD75-E2AB6215D345} = {19CBCE06-3F5C-479A-BD75-E2AB6215D345}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsonrpc", "jsonrpc\jsonrpc.vcxproj", "{8DD52FAC-ECEE-48C2-B266-E7C47ED485F8}"
ProjectSection(ProjectDependencies) = postProject
@@ -46,6 +49,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "discovery", "components\dis
{C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mmatch", "mmatch\mmatch.vcxproj", "{19CBCE06-3F5C-479A-BD75-E2AB6215D345}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -88,6 +93,10 @@ Global
{EAD41628-BB96-4F99-9070-8A9676801295}.Debug|Win32.Build.0 = Debug|Win32
{EAD41628-BB96-4F99-9070-8A9676801295}.Release|Win32.ActiveCfg = Release|Win32
{EAD41628-BB96-4F99-9070-8A9676801295}.Release|Win32.Build.0 = Release|Win32
+ {19CBCE06-3F5C-479A-BD75-E2AB6215D345}.Debug|Win32.ActiveCfg = Debug|Win32
+ {19CBCE06-3F5C-479A-BD75-E2AB6215D345}.Debug|Win32.Build.0 = Debug|Win32
+ {19CBCE06-3F5C-479A-BD75-E2AB6215D345}.Release|Win32.ActiveCfg = Release|Win32
+ {19CBCE06-3F5C-479A-BD75-E2AB6215D345}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp
index 8fd2f318d..1419039c6 100644
--- a/icinga/icingaapplication.cpp
+++ b/icinga/icingaapplication.cpp
@@ -30,14 +30,14 @@ int IcingaApplication::Main(const vector& args)
/* register handler for 'icinga' config objects */
ConfigCollection::Ptr icingaCollection = GetConfigHive()->GetCollection("icinga");
function NewIcingaConfigHandler = bind_weak(&IcingaApplication::NewIcingaConfigHandler, shared_from_this());
- icingaCollection->OnObjectCreated += NewIcingaConfigHandler;
+ icingaCollection->OnObjectCommitted += NewIcingaConfigHandler;
icingaCollection->ForEachObject(NewIcingaConfigHandler);
icingaCollection->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedIcingaConfigHandler, shared_from_this());
/* register handler for 'component' config objects */
ConfigCollection::Ptr componentCollection = GetConfigHive()->GetCollection("component");
function NewComponentHandler = bind_weak(&IcingaApplication::NewComponentHandler, shared_from_this());
- componentCollection->OnObjectCreated += NewComponentHandler;
+ componentCollection->OnObjectCommitted += NewComponentHandler;
componentCollection->ForEachObject(NewComponentHandler);
componentCollection->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedComponentHandler, shared_from_this());
diff --git a/mmatch/Makefile.am b/mmatch/Makefile.am
new file mode 100644
index 000000000..453ad3640
--- /dev/null
+++ b/mmatch/Makefile.am
@@ -0,0 +1,9 @@
+## Process this file with automake to produce Makefile.in
+
+
+noinst_LTLIBRARIES = \
+ libmmatch.la
+
+libmmatch_la_SOURCES = \
+ mmatch.c \
+ mmatch.h
diff --git a/mmatch/mmatch.c b/mmatch/mmatch.c
new file mode 100644
index 000000000..10b8ce300
--- /dev/null
+++ b/mmatch/mmatch.c
@@ -0,0 +1,305 @@
+/*
+ * IRC - Internet Relay Chat, common/match.c
+ * Copyright (C) 1990 Jarkko Oikarinen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: Match.cpp,v 1.2 2005/08/15 10:08:50 shroud23 Exp $
+ */
+
+#include
+#include "mmatch.h"
+
+#define ToLower tolower
+
+/*
+ * mmatch()
+ *
+ * Written by Run (carlo@runaway.xs4all.nl), 25-10-96
+ *
+ *
+ * From: Carlo Wood
+ * Message-Id: <199609021026.MAA02393@runaway.xs4all.nl>
+ * Subject: [C-Com] Analysis for `mmatch' (was: gline4 problem)
+ * To: coder-com@mail.undernet.org (coder committee)
+ * Date: Mon, 2 Sep 1996 12:26:01 +0200 (MET DST)
+ *
+ * We need a new function `mmatch(const char *old_mask, const char *new_mask)'
+ * which returns `true' likewise the current `match' (start with copying it),
+ * but which treats '*' and '?' in `new_mask' differently (not "\*" and "\?" !)
+ * as follows: a '*' in `new_mask' does not match a '?' in `old_mask' and
+ * a '?' in `new_mask' does not match a '\?' in `old_mask'.
+ * And ofcourse... a '*' in `new_mask' does not match a '\*' in `old_mask'...
+ * And last but not least, '\?' and '\*' in `new_mask' now become one character.
+ */
+
+int mmatch(const char *old_mask, const char *new_mask)
+{
+ const char *m = old_mask;
+ const char *n = new_mask;
+ const char *ma = m;
+ const char *na = n;
+ int wild = 0;
+ int mq = 0, nq = 0;
+
+ while (1)
+ {
+ if (*m == '*')
+ {
+ while (*m == '*')
+ m++;
+ wild = 1;
+ ma = m;
+ na = n;
+ }
+
+ if (!*m)
+ {
+ if (!*n)
+ return 0;
+ for (m--; (m > old_mask) && (*m == '?'); m--)
+ ;
+ if ((*m == '*') && (m > old_mask) && (m[-1] != '\\'))
+ return 0;
+ if (!wild)
+ return 1;
+ m = ma;
+
+ /* Added to `mmatch' : Because '\?' and '\*' now is one character: */
+ if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?')))
+ ++na;
+
+ n = ++na;
+ }
+ else if (!*n)
+ {
+ while (*m == '*')
+ m++;
+ return (*m != 0);
+ }
+ if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
+ {
+ m++;
+ mq = 1;
+ }
+ else
+ mq = 0;
+
+ /* Added to `mmatch' : Because '\?' and '\*' now is one character: */
+ if ((*n == '\\') && ((n[1] == '*') || (n[1] == '?')))
+ {
+ n++;
+ nq = 1;
+ }
+ else
+ nq = 0;
+
+/*
+ * This `if' has been changed compared to match() to do the following:
+ * Match when:
+ * old (m) new (n) boolean expression
+ * * any (*m == '*' && !mq) ||
+ * ? any except '*' (*m == '?' && !mq && (*n != '*' || nq)) ||
+ * any except * or ? same as m (!((*m == '*' || *m == '?') && !mq) &&
+ * ToLower(*m) == ToLower(*n) &&
+ * !((mq && !nq) || (!mq && nq)))
+ *
+ * Here `any' also includes \* and \? !
+ *
+ * After reworking the boolean expressions, we get:
+ * (Optimized to use boolean shortcircuits, with most frequently occuring
+ * cases upfront (which took 2 hours!)).
+ */
+ if ((*m == '*' && !mq) ||
+ ((!mq || nq) && ToLower(*m) == ToLower(*n)) ||
+ (*m == '?' && !mq && (*n != '*' || nq)))
+ {
+ if (*m)
+ m++;
+ if (*n)
+ n++;
+ }
+ else
+ {
+ if (!wild)
+ return 1;
+ m = ma;
+
+ /* Added to `mmatch' : Because '\?' and '\*' now is one character: */
+ if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?')))
+ ++na;
+
+ n = ++na;
+ }
+ }
+}
+
+/*
+ * Compare if a given string (name) matches the given
+ * mask (which can contain wild cards: '*' - match any
+ * number of chars, '?' - match any single character.
+ *
+ * return 0, if match
+ * 1, if no match
+ */
+
+/*
+ * match
+ *
+ * Rewritten by Andrea Cocito (Nemesi), November 1998.
+ *
+ */
+
+/****************** Nemesi's match() ***************/
+
+int match(const char *mask, const char *string)
+{
+ const char *m = mask, *s = string;
+ char ch;
+ const char *bm, *bs; /* Will be reg anyway on a decent CPU/compiler */
+
+ /* Process the "head" of the mask, if any */
+ while ((ch = *m++) && (ch != '*'))
+ switch (ch)
+ {
+ case '\\':
+ if (*m == '?' || *m == '*')
+ ch = *m++;
+ default:
+ if (ToLower(*s) != ToLower(ch))
+ return 1;
+ case '?':
+ if (!*s++)
+ return 1;
+ };
+ if (!ch)
+ return *s;
+
+ /* We got a star: quickly find if/where we match the next char */
+got_star:
+ bm = m; /* Next try rollback here */
+ while ((ch = *m++))
+ switch (ch)
+ {
+ case '?':
+ if (!*s++)
+ return 1;
+ case '*':
+ bm = m;
+ continue; /* while */
+ case '\\':
+ if (*m == '?' || *m == '*')
+ ch = *m++;
+ default:
+ goto break_while; /* C is structured ? */
+ };
+break_while:
+ if (!ch)
+ return 0; /* mask ends with '*', we got it */
+ ch = ToLower(ch);
+ if (!*s) /* String is already empty, don't continue */
+ return 1; /* This fixes the #quakenet access denied bug */
+ while (ToLower(*s++) != ch)
+ if (!*s)
+ return 1;
+ bs = s; /* Next try start from here */
+
+ /* Check the rest of the "chunk" */
+ while ((ch = *m++))
+ {
+ switch (ch)
+ {
+ case '*':
+ goto got_star;
+ case '\\':
+ if (*m == '?' || *m == '*')
+ ch = *m++;
+ default:
+ if (ToLower(*s) != ToLower(ch))
+ {
+ /* If we've run out of string, give up */
+ if (!*bs)
+ return 1;
+ m = bm;
+ s = bs;
+ goto got_star;
+ };
+ case '?':
+ if (!*s++)
+ return 1;
+ };
+ };
+ if (*s)
+ {
+ m = bm;
+ s = bs;
+ goto got_star;
+ };
+ return 0;
+}
+
+/*
+ * collapse()
+ * Collapse a pattern string into minimal components.
+ * This particular version is "in place", so that it changes the pattern
+ * which is to be reduced to a "minimal" size.
+ *
+ * (C) Carlo Wood - 6 Oct 1998
+ * Speedup rewrite by Andrea Cocito, December 1998.
+ * Note that this new optimized alghoritm can *only* work in place.
+ */
+
+char *collapse(char *mask)
+{
+ int star = 0;
+ char *m = mask;
+ char *b;
+
+ if (m)
+ {
+ do
+ {
+ if ((*m == '*') && ((m[1] == '*') || (m[1] == '?')))
+ {
+ b = m;
+ do
+ {
+ if (*m == '*')
+ star = 1;
+ else
+ {
+ if (star && (*m != '?'))
+ {
+ *b++ = '*';
+ star = 0;
+ };
+ *b++ = *m;
+ if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
+ *b++ = *++m;
+ };
+ }
+ while (*m++);
+ break;
+ }
+ else
+ {
+ if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
+ m++;
+ };
+ }
+ while (*m++);
+ };
+ return mask;
+}
\ No newline at end of file
diff --git a/mmatch/mmatch.h b/mmatch/mmatch.h
new file mode 100644
index 000000000..3a48c202f
--- /dev/null
+++ b/mmatch/mmatch.h
@@ -0,0 +1,16 @@
+#ifndef MMATCH_H
+#define MMATCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int mmatch(const char *old_mask, const char *new_mask);
+int match(const char *ma, const char *na);
+char *collapse(char *pattern);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* MMATCH_H */
diff --git a/mmatch/mmatch.vcxproj b/mmatch/mmatch.vcxproj
new file mode 100644
index 000000000..40d9905b5
--- /dev/null
+++ b/mmatch/mmatch.vcxproj
@@ -0,0 +1,80 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+
+
+
+
+
+
+ {19CBCE06-3F5C-479A-BD75-E2AB6215D345}
+ Win32Proj
+ mmatch
+
+
+
+ StaticLibrary
+ true
+ Unicode
+
+
+ StaticLibrary
+ false
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file