process.h \
ringbuffer.cpp \
ringbuffer.h \
+ scriptfunction.cpp \
+ scriptfunction.h \
+ scripttask.cpp \
+ scripttask.h \
socket.cpp \
socket.h \
streamlogger.cpp \
void Start(void);
+ void Finish(void);
+
protected:
virtual void Run(void) = 0;
- void Finish(void);
-
private:
void ForwardCallback(void);
<ClCompile Include="objectset.cpp" />
<ClCompile Include="process.cpp" />
<ClCompile Include="ringbuffer.cpp" />
+ <ClCompile Include="scriptfunction.cpp" />
+ <ClCompile Include="scripttask.cpp" />
<ClCompile Include="socket.cpp" />
<ClCompile Include="streamlogger.cpp" />
<ClCompile Include="sysloglogger.cpp" />
<ClInclude Include="configobject.h" />
<ClInclude Include="dictionary.h" />
<ClInclude Include="event.h" />
+ <ClInclude Include="scriptfunction.h" />
+ <ClInclude Include="scripttask.h" />
<ClInclude Include="logger.h" />
<ClInclude Include="objectmap.h" />
<ClInclude Include="objectset.h" />
<ClCompile Include="asynctask.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
+ <ClCompile Include="scriptfunction.cpp">
+ <Filter>Quelldateien</Filter>
+ </ClCompile>
+ <ClCompile Include="scripttask.cpp">
+ <Filter>Quelldateien</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="application.h">
<ClInclude Include="process.h">
<Filter>Headerdateien</Filter>
</ClInclude>
+ <ClInclude Include="scripttask.h">
+ <Filter>Headerdateien</Filter>
+ </ClInclude>
+ <ClInclude Include="scriptfunction.h">
+ <Filter>Headerdateien</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Quelldateien">
bool ConfigObject::TypeAndNameGetter(const ConfigObject::Ptr& object, pair<string, string> *key)
{
- *key = make_pair(object->GetType(), object->GetName());
+ *key = make_pair(object->GetType(), object->GetName());
- return true;
+ return true;
}
function<bool (ConfigObject::Ptr)> ConfigObject::MakeTypePredicate(string type)
{
GetTags()->Remove(key);
}
+
+ScriptTask::Ptr ConfigObject::InvokeHook(const string& hook,
+ const vector<Variant>& arguments, AsyncTask::CompletionCallback callback)
+{
+ Dictionary::Ptr hooks;
+ string funcName;
+ if (!GetProperty("hooks", &hooks) || !hooks->Get(hook, &funcName))
+ return ScriptTask::Ptr();
+
+ ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName);
+
+ if (!func)
+ throw invalid_argument("Function '" + funcName + "' does not exist.");
+
+ ScriptTask::Ptr task = boost::make_shared<ScriptTask>(func, arguments, callback);
+ task->Start();
+
+ return task;
+}
void RemoveTag(const string& key);
+ ScriptTask::Ptr InvokeHook(const string& hook,
+ const vector<Variant>& arguments, AsyncTask::CompletionCallback callback);
+
string GetType(void) const;
string GetName(void) const;
void SetCommitTimestamp(time_t ts);
static bool TypeAndNameGetter(const ConfigObject::Ptr& object, pair<string, string> *key);
- static bool TypePredicate(const ConfigObject::Ptr& object, string type);
+ static bool TypePredicate(const ConfigObject::Ptr& object, string type);
static bool TypeGetter(const ConfigObject::Ptr& object, string *key);
};
#include "tcpclient.h"
#include "tcpserver.h"
#include "tlsclient.h"
+#include "asynctask.h"
+#include "process.h"
+#include "scriptfunction.h"
+#include "scripttask.h"
#include "objectset.h"
#include "objectmap.h"
#include "configobject.h"
#include "logger.h"
#include "streamlogger.h"
#include "sysloglogger.h"
-#include "asynctask.h"
-#include "process.h"
#endif /* I2BASE_H */
--- /dev/null
+#include "i2-base.h"
+
+using namespace icinga;
+
+map<string, ScriptFunction::Ptr> ScriptFunction::m_Functions;
+
+ScriptFunction::ScriptFunction(const Callback& function)
+ : m_Callback(function)
+{ }
+
+void ScriptFunction::Register(const string& name, const ScriptFunction::Ptr& function)
+{
+ m_Functions[name] = function;
+}
+
+void ScriptFunction::Unregister(const string& name)
+{
+ m_Functions.erase(name);
+}
+
+ScriptFunction::Ptr ScriptFunction::GetByName(const string& name)
+{
+ map<string, ScriptFunction::Ptr>::iterator it;
+
+ it = m_Functions.find(name);
+
+ if (it == m_Functions.end())
+ return ScriptFunction::Ptr();
+
+ return it->second;
+}
+
+void ScriptFunction::Invoke(const ScriptTask::Ptr& task, const vector<Variant>& arguments)
+{
+ m_Callback(task, arguments);
+}
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
+ * *
+ * 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 2 *
+ * of the License, 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#ifndef SCRIPTFUNCTION_H
+#define SCRIPTFUNCTION_H
+
+namespace icinga
+{
+
+class ScriptTask;
+
+class I2_BASE_API ScriptFunction : public Object
+{
+public:
+ typedef shared_ptr<ScriptFunction> Ptr;
+ typedef weak_ptr<ScriptFunction> WeakPtr;
+
+ typedef function<void (const shared_ptr<ScriptTask>&, const vector<Variant>& arguments)> Callback;
+
+ ScriptFunction(const Callback& function);
+
+ static void Register(const string& name, const ScriptFunction::Ptr& function);
+ static void Unregister(const string& name);
+ static ScriptFunction::Ptr GetByName(const string& name);
+
+ void Invoke(const shared_ptr<ScriptTask>& task, const vector<Variant>& arguments);
+
+private:
+ Callback m_Callback;
+
+ static map<string, ScriptFunction::Ptr> m_Functions;
+};
+
+}
+
+#endif /* SCRIPTFUNCTION_H */
\ No newline at end of file
--- /dev/null
+#include "i2-base.h"
+
+using namespace icinga;
+
+ScriptTask::ScriptTask(const ScriptFunction::Ptr& function, const vector<Variant>& arguments, CompletionCallback callback)
+ : AsyncTask(callback), m_Function(function), m_Arguments(arguments)
+{ }
+
+void ScriptTask::Run(void)
+{
+ m_Function->Invoke(GetSelf(), m_Arguments);
+}
+
+void ScriptTask::SetResult(const Variant& result)
+{
+ m_Result = result;
+}
+
+Variant ScriptTask::GetResult(void)
+{
+ return m_Result;
+}
\ No newline at end of file
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
+ * *
+ * 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 2 *
+ * of the License, 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#ifndef SCRIPTTASK_H
+#define SCRIPTTASK_H
+
+namespace icinga
+{
+
+class I2_BASE_API ScriptTask : public AsyncTask
+{
+public:
+ typedef shared_ptr<ScriptTask> Ptr;
+ typedef weak_ptr<ScriptTask> WeakPtr;
+
+ ScriptTask(const ScriptFunction::Ptr& function, const vector<Variant>& arguments, CompletionCallback callback);
+
+ void SetResult(const Variant& result);
+ Variant GetResult(void);
+
+protected:
+ virtual void Run(void);
+
+private:
+ ScriptFunction::Ptr m_Function;
+ vector<Variant> m_Arguments;
+ Variant m_Result;
+};
+
+}
+
+#endif /* SCRIPTTASK_H */
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="checkresult.h" />
- <ClInclude Include="checktask.h" />
<ClInclude Include="cib.h" />
<ClInclude Include="configobjectadapter.h" />
<ClInclude Include="host.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="checkresult.cpp" />
- <ClCompile Include="checktask.cpp" />
<ClCompile Include="cib.cpp" />
<ClCompile Include="configobjectadapter.cpp" />
<ClCompile Include="host.cpp" />
<ClInclude Include="checkresult.h">
<Filter>Headerdateien</Filter>
</ClInclude>
- <ClInclude Include="checktask.h">
- <Filter>Headerdateien</Filter>
- </ClInclude>
<ClInclude Include="cib.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClCompile Include="checkresult.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
- <ClCompile Include="checktask.cpp">
- <Filter>Quelldateien</Filter>
- </ClCompile>
<ClCompile Include="cib.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
{
m_ConfigObject->RemoveTag(key);
}
+
+ScriptTask::Ptr ConfigObjectAdapter::InvokeHook(const string& hook,
+ const vector<Variant>& arguments, AsyncTask::CompletionCallback callback)
+{
+ return m_ConfigObject->InvokeHook(hook, arguments, callback);
+}
\ No newline at end of file
void RemoveTag(const string& key);
+ ScriptTask::Ptr InvokeHook(const string& hook,
+ const vector<Variant>& arguments, AsyncTask::CompletionCallback callback);
+
private:
ConfigObject::Ptr m_ConfigObject;
};
using namespace icinga;
-NagiosCheckTask::NagiosCheckTask(const Service& service, const CompletionCallback& completionCallback)
- : CheckTask(service, completionCallback)
+void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments)
{
+ if (arguments.size() < 1)
+ throw invalid_argument("Missing argument: Service must be specified.");
+
+ Variant vservice = arguments[0];
+ if (!vservice.IsObjectType<ConfigObject>())
+ throw invalid_argument("Argument must be a config object.");
+
+ Service service = static_cast<ConfigObject::Ptr>(vservice);
+
string checkCommand = service.GetCheckCommand();
vector<Dictionary::Ptr> macroDicts;
macroDicts.push_back(service.GetMacros());
macroDicts.push_back(service.GetHost().GetMacros());
macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros());
- m_Command = MacroProcessor::ResolveMacros(checkCommand, macroDicts);
-}
+ string command = MacroProcessor::ResolveMacros(checkCommand, macroDicts);
+
+ CheckResult result;
-void NagiosCheckTask::Run(void)
-{
time_t now;
time(&now);
- GetResult().SetScheduleStart(now);
+ result.SetScheduleStart(now);
- m_Process = boost::make_shared<Process>(m_Command, boost::bind(&NagiosCheckTask::ProcessFinishedHandler, static_cast<NagiosCheckTask::Ptr>(GetSelf())));
- m_Process->Start();
+ Process::Ptr process = boost::make_shared<Process>(command, boost::bind(&NagiosCheckTask::ProcessFinishedHandler, task, _1, result));
+ process->Start();
}
-void NagiosCheckTask::ProcessFinishedHandler(void)
+void NagiosCheckTask::ProcessFinishedHandler(const ScriptTask::Ptr& task, const AsyncTask::Ptr& aprocess, CheckResult result)
{
- GetResult().SetExecutionStart(m_Process->GetExecutionStart());
- GetResult().SetExecutionEnd(m_Process->GetExecutionEnd());
+ Process::Ptr process = static_pointer_cast<Process>(aprocess);
+
+ result.SetExecutionStart(process->GetExecutionStart());
+ result.SetExecutionEnd(process->GetExecutionEnd());
- string output = m_Process->GetOutput();
- long exitcode = m_Process->GetExitStatus();
- m_Process.reset();
+ string output = process->GetOutput();
+ long exitcode = process->GetExitStatus();
boost::algorithm::trim(output);
- ProcessCheckOutput(output);
+ ProcessCheckOutput(result, output);
ServiceState state;
break;
}
- GetResult().SetState(state);
+ result.SetState(state);
time_t now;
time(&now);
- GetResult().SetScheduleEnd(now);
+ result.SetScheduleEnd(now);
- Finish();
+ task->SetResult(result.GetDictionary());
+ task->Finish();
}
-void NagiosCheckTask::ProcessCheckOutput(const string& output)
+void NagiosCheckTask::ProcessCheckOutput(CheckResult& result, const string& output)
{
string text;
string perfdata;
}
}
- GetResult().SetOutput(text);
- GetResult().SetPerformanceDataRaw(perfdata);
-}
-
-CheckTask::Ptr NagiosCheckTask::CreateTask(const Service& service, const CompletionCallback& completionCallback)
-{
- return boost::make_shared<NagiosCheckTask>(service, completionCallback);
+ result.SetOutput(text);
+ result.SetPerformanceDataRaw(perfdata);
}
void NagiosCheckTask::Register(void)
{
- CheckTask::RegisterType("nagios", NagiosCheckTask::CreateTask);
+ ScriptFunction::Ptr func = boost::make_shared<ScriptFunction>(&NagiosCheckTask::ScriptFunc);
+ ScriptFunction::Register("builtin::NagiosCheck", func);
}
namespace icinga
{
-class I2_CIB_API NagiosCheckTask : public CheckTask
+class I2_CIB_API NagiosCheckTask
{
public:
- typedef shared_ptr<NagiosCheckTask> Ptr;
- typedef weak_ptr<NagiosCheckTask> WeakPtr;
-
- NagiosCheckTask(const Service& service, const CompletionCallback& completionCallback);
-
- static CheckTask::Ptr CreateTask(const Service& service, const CompletionCallback& completionCallback);
+ static void ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments);
static void Register(void);
private:
- string m_Command;
- Process::Ptr m_Process;
-
- virtual void Run(void);
- void ProcessFinishedHandler(void);
- void ProcessCheckOutput(const string& output);
+ static void ProcessFinishedHandler(const ScriptTask::Ptr& task, const AsyncTask::Ptr& aprocess, CheckResult result);
+ static void ProcessCheckOutput(CheckResult& result, const string& output);
};
}
return macros;
}
-string Service::GetCheckType(void) const
-{
- string value = "nagios";
- GetProperty("check_type", &value);
- return value;
-}
-
string Service::GetCheckCommand(void) const
{
string value;
result->Set(name, name);
}
- return result;
+ return result;
}
string GetAlias(void) const;
Host GetHost(void) const;
Dictionary::Ptr GetMacros(void) const;
- string GetCheckType(void) const;
string GetCheckCommand(void) const;
long GetMaxCheckAttempts(void) const;
long GetCheckInterval(void) const;
Logger::Write(LogDebug, "checker", "Executing service check for '" + service.GetName() + "'");
+ vector<Variant> arguments;
+ arguments.push_back(service.GetConfigObject());
+ ScriptTask::Ptr task;
+ task = service.InvokeHook("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1));
+ assert(task); /* TODO: gracefully handle missing hooks */
+
m_PendingServices.insert(service.GetConfigObject());
- CheckTask::Ptr task = CheckTask::CreateTask(service, boost::bind(&CheckerComponent::CheckCompletedHandler, this, _1));
- task->Start();
+ /*CheckTask::Ptr task = CheckTask::CreateTask(service, boost::bind(&CheckerComponent::CheckCompletedHandler, this, _1));
+ task->Start();*/
service.SetTag("current_task", task);
Logger::Write(LogInformation, "checker", msgbuf.str());
}
-void CheckerComponent::CheckCompletedHandler(const AsyncTask::Ptr& atask)
+void CheckerComponent::CheckCompletedHandler(Service& service, const AsyncTask::Ptr& atask)
{
- CheckTask::Ptr task = static_pointer_cast<CheckTask>(atask);
- Service service = task->GetService();
+ ScriptTask::Ptr task = static_pointer_cast<ScriptTask>(atask);
service.RemoveTag("current_task");
if (m_PendingServices.find(service.GetConfigObject()) == m_PendingServices.end())
return;
- CheckResult result = task->GetResult();
+ /* remove the service from the list of pending services */
+ m_PendingServices.erase(service.GetConfigObject());
+ m_Services.push(service);
+
+ Variant vresult = task->GetResult();
+ if (!vresult.IsObjectType<Dictionary>())
+ return;
+
+ CheckResult result = static_cast<Dictionary::Ptr>(vresult);
+
Logger::Write(LogDebug, "checker", "Got result for service '" + service.GetName() + "'");
long execution_time = result.GetExecutionEnd() - result.GetExecutionStart();
/* figure out when the next check is for this service */
service.UpdateNextCheck();
- /* remove the service from the list of pending services */
- m_PendingServices.erase(service.GetConfigObject());
- m_Services.push(service);
-
RequestMessage rm;
rm.SetMethod("checker::CheckResult");
void CheckTimerHandler(void);
void ResultTimerHandler(void);
- void CheckCompletedHandler(const AsyncTask::Ptr& task);
+ void CheckCompletedHandler(Service& service, const AsyncTask::Ptr& atask);
void AdjustCheckTimer(void);
}
abstract object service "nagios-service" {
- check_type = "nagios",
+ hooks = {
+ check = "builtin::NagiosCheck"
+ },
macros = {
plugindir = "/usr/local/icinga/libexec"
: m_PidPath(DefaultPidPath)
{ }
+void TestScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments)
+{
+ std::cout << "Got " << arguments.size() << " arguments." << std::endl;
+ task->Finish();
+}
+
/**
* The entry point for the Icinga application.
*