Implement basic actions framework

refs #9080
This commit is contained in:
Jean-Marcel Flach 2015-07-30 17:50:17 +02:00 committed by Michael Friedrich
parent 625a7eafbe
commit 9b6ebbc69b
11 changed files with 365 additions and 17 deletions

View File

@ -41,7 +41,7 @@ mkclass_target(user.ti user.tcpp user.thpp)
mkembedconfig_target(icinga-app.conf icinga-app.cpp) mkembedconfig_target(icinga-app.conf icinga-app.cpp)
set(icinga_SOURCES set(icinga_SOURCES
api.cpp apievents.cpp checkable.cpp checkable.thpp checkable-dependency.cpp checkable-downtime.cpp checkable-event.cpp api.cpp apiactions.cpp apievents.cpp checkable.cpp checkable.thpp checkable-dependency.cpp checkable-downtime.cpp checkable-event.cpp
checkable-flapping.cpp checkcommand.cpp checkcommand.thpp checkresult.cpp checkresult.thpp checkable-flapping.cpp checkcommand.cpp checkcommand.thpp checkresult.cpp checkresult.thpp
cib.cpp command.cpp command.thpp comment.cpp comment.thpp compatutility.cpp dependency.cpp dependency.thpp cib.cpp command.cpp command.thpp comment.cpp comment.thpp compatutility.cpp dependency.cpp dependency.thpp
dependency-apply.cpp downtime.cpp downtime.thpp eventcommand.cpp eventcommand.thpp dependency-apply.cpp downtime.cpp downtime.thpp eventcommand.cpp eventcommand.thpp

48
lib/icinga/apiactions.cpp Normal file
View File

@ -0,0 +1,48 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2015 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. *
******************************************************************************/
#include "icinga/apiactions.hpp"
#include "icinga/service.hpp"
#include "remote/apiaction.hpp"
#include "remote/httputility.hpp"
#include "base/utility.hpp"
#include "base/convert.hpp"
using namespace icinga;
REGISTER_APIACTION(reschedule_check, "Service;Host", &ApiActions::RescheduleCheck);
Dictionary::Ptr ApiActions::RescheduleCheck(const DynamicObject::Ptr& object, const Dictionary::Ptr& params)
{
Checkable::Ptr checkable = static_pointer_cast<Checkable>(object);
if (Convert::ToBool(HttpUtility::GetLastParameter(params, "force")))
checkable->SetForceNextCheck(true);
double nextCheck;
if (params->Contains("next_check"))
nextCheck = HttpUtility::GetLastParameter(params, "next_check");
else
nextCheck = Utility::GetTime();
checkable->SetNextCheck(nextCheck);
Dictionary::Ptr result = new Dictionary();
result->Set("code", 200);
result->Set("status", "yay");
return result;
}

41
lib/icinga/apiactions.hpp Normal file
View File

@ -0,0 +1,41 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2015 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 APIACTIONS_H
#define APIACTIONS_H
#include "icinga/i2-icinga.hpp"
#include "base/dynamicobject.hpp"
#include "base/dictionary.hpp"
namespace icinga
{
/**
* @ingroup icinga
*/
class I2_ICINGA_API ApiActions
{
public:
static Dictionary::Ptr RescheduleCheck(const DynamicObject::Ptr& object, const Dictionary::Ptr& params);
};
}
#endif /* APIACTIONS_H */

View File

@ -21,14 +21,14 @@ mkclass_target(endpoint.ti endpoint.tcpp endpoint.thpp)
mkclass_target(zone.ti zone.tcpp zone.thpp) mkclass_target(zone.ti zone.tcpp zone.thpp)
set(remote_SOURCES set(remote_SOURCES
actionshandler.cpp apiaction.cpp
apifunction.cpp apilistener.cpp apilistener.thpp apilistener-sync.cpp apifunction.cpp apilistener.cpp apilistener.thpp apilistener-sync.cpp
apiuser.cpp apiuser.thpp authority.cpp base64.cpp configfileshandler.cpp apiuser.cpp apiuser.thpp authority.cpp base64.cpp configfileshandler.cpp
configmoduleshandler.cpp configmoduleutility.cpp configstageshandler.cpp configmoduleshandler.cpp configmoduleutility.cpp configstageshandler.cpp
endpoint.cpp endpoint.thpp filterutility.cpp endpoint.cpp endpoint.thpp filterutility.cpp
httpchunkedencoding.cpp httpconnection.cpp httphandler.cpp httprequest.cpp httpresponse.cpp httpchunkedencoding.cpp httpconnection.cpp httphandler.cpp httprequest.cpp httpresponse.cpp
httputility.cpp jsonrpc.cpp jsonrpcconnection.cpp jsonrpcconnection-heartbeat.cpp httputility.cpp jsonrpc.cpp jsonrpcconnection.cpp jsonrpcconnection-heartbeat.cpp
messageorigin.cpp statusqueryhandler.cpp zone.cpp zone.thpp messageorigin.cpp statusqueryhandler.cpp url.cpp zone.cpp zone.thpp
url.cpp
) )
if(ICINGA2_UNITY_BUILD) if(ICINGA2_UNITY_BUILD)

View File

@ -0,0 +1,83 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2015 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. *
******************************************************************************/
#include "remote/actionshandler.hpp"
#include "remote/httputility.hpp"
#include "remote/filterutility.hpp"
#include "remote/apiaction.hpp"
#include "base/exception.hpp"
#include "base/serializer.hpp"
#include <boost/algorithm/string.hpp>
#include <set>
using namespace icinga;
REGISTER_URLHANDLER("/v1/actions", ActionsHandler);
bool ActionsHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
if (request.RequestUrl->GetPath().size() < 3)
return false;
if (request.RequestMethod != "POST") {
response.SetStatus(400, "Bad request");
return true;
}
String actionName = request.RequestUrl->GetPath()[2];
ApiAction::Ptr action = ApiAction::GetByName(actionName);
if (!action)
return false;
QueryDescription qd;
BOOST_FOREACH(const String& typeName, action->GetTypes()) {
Type::Ptr type = Type::GetByName(typeName);
ASSERT(type);
qd.Types.insert(type);
}
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
std::vector<DynamicObject::Ptr> objs = FilterUtility::GetFilterTargets(qd, params);
Array::Ptr results = new Array();
BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) {
try {
results->Add(action->Invoke(obj, params));
} catch (const std::exception& ex) {
Dictionary::Ptr fail = new Dictionary();
fail->Set("code", 501);
fail->Set("status", "Error: " + DiagnosticInformation(ex));
results->Add(fail);
}
}
Dictionary::Ptr result = new Dictionary();
result->Set("results", results);
response.SetStatus(200, "OK");
HttpUtility::SendJsonBody(response, result);
return true;
}

View File

@ -0,0 +1,38 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2015 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 ACTIONSHANDLER_H
#define ACTIONSHANDLER_H
#include "remote/httphandler.hpp"
namespace icinga
{
class I2_REMOTE_API ActionsHandler : public HttpHandler
{
public:
DECLARE_PTR_TYPEDEFS(ActionsHandler);
virtual bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response);
};
}
#endif /* ACTIONSHANDLER_H */

57
lib/remote/apiaction.cpp Normal file
View File

@ -0,0 +1,57 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2015 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. *
******************************************************************************/
#include "remote/apiaction.hpp"
#include "base/singleton.hpp"
using namespace icinga;
ApiAction::ApiAction(const std::vector<String>& types, const Callback& action)
: m_Types(types), m_Callback(action)
{ }
Value ApiAction::Invoke(const DynamicObject::Ptr& target, const Dictionary::Ptr& params)
{
return m_Callback(target, params);
}
const std::vector<String>& ApiAction::GetTypes(void) const
{
return m_Types;
}
ApiAction::Ptr ApiAction::GetByName(const String& name)
{
return ApiActionRegistry::GetInstance()->GetItem(name);
}
void ApiAction::Register(const String& name, const ApiAction::Ptr& action)
{
ApiActionRegistry::GetInstance()->Register(name, action);
}
void ApiAction::Unregister(const String& name)
{
ApiActionRegistry::GetInstance()->Unregister(name);
}
ApiActionRegistry *ApiActionRegistry::GetInstance(void)
{
return Singleton<ApiActionRegistry>::GetInstance();
}

92
lib/remote/apiaction.hpp Normal file
View File

@ -0,0 +1,92 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2015 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 APIACTION_H
#define APIACTION_H
#include "remote/i2-remote.hpp"
#include "base/registry.hpp"
#include "base/value.hpp"
#include "base/dictionary.hpp"
#include "base/dynamicobject.hpp"
#include <vector>
#include <boost/function.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
namespace icinga
{
/**
* An API action.
*
* @ingroup remote
*/
class I2_REMOTE_API ApiAction : public Object
{
public:
DECLARE_PTR_TYPEDEFS(ApiAction);
typedef boost::function<Value(const DynamicObject::Ptr& target, const Dictionary::Ptr& params)> Callback;
ApiAction(const std::vector<String>& registerTypes, const Callback& function);
Value Invoke(const DynamicObject::Ptr& target, const Dictionary::Ptr& params);
const std::vector<String>& GetTypes(void) const;
static ApiAction::Ptr GetByName(const String& name);
static void Register(const String& name, const ApiAction::Ptr& action);
static void Unregister(const String& name);
private:
std::vector<String> m_Types;
Callback m_Callback;
};
/**
* A registry for API actions.
*
* @ingroup remote
*/
class I2_REMOTE_API ApiActionRegistry : public Registry<ApiActionRegistry, ApiAction::Ptr>
{
public:
static ApiActionRegistry *GetInstance(void);
};
#define REGISTER_APIACTION(name, types, callback) \
namespace { namespace UNIQUE_NAME(apia) { namespace apia ## name { \
void RegisterAction(void) \
{ \
String registerName = #name; \
boost::algorithm::replace_all(registerName, "_", "-"); \
std::vector<String> registerTypes; \
String typeNames = types; \
boost::algorithm::split(registerTypes, typeNames, boost::is_any_of(";")); \
ApiAction::Ptr action = new ApiAction(registerTypes, callback); \
ApiActionRegistry::GetInstance()->Register(registerName, action); \
} \
INITIALIZE_ONCE(RegisterAction); \
} } }
}
#endif /* APIACTION_H */

View File

@ -66,17 +66,6 @@ public:
static ApiFunctionRegistry *GetInstance(void); static ApiFunctionRegistry *GetInstance(void);
}; };
/**
* Helper class for registering ApiFunction implementation classes.
*
* @ingroup base
*/
class I2_REMOTE_API RegisterApiFunctionHelper
{
public:
RegisterApiFunctionHelper(const String& name, const ApiFunction::Callback& function);
};
#define REGISTER_APIFUNCTION(name, ns, callback) \ #define REGISTER_APIFUNCTION(name, ns, callback) \
namespace { namespace UNIQUE_NAME(apif) { namespace apif ## name { \ namespace { namespace UNIQUE_NAME(apif) { namespace apif ## name { \
void RegisterFunction(void) \ void RegisterFunction(void) \

View File

@ -56,7 +56,7 @@ void HttpUtility::SendJsonBody(HttpResponse& response, const Value& val)
response.WriteBody(body.CStr(), body.GetLength()); response.WriteBody(body.CStr(), body.GetLength());
} }
String HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String& key) Value HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String& key)
{ {
Value varr = params->Get(key); Value varr = params->Get(key);
@ -66,7 +66,7 @@ String HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String
Array::Ptr arr = varr; Array::Ptr arr = varr;
if (arr->GetLength() == 0) if (arr->GetLength() == 0)
return String(); return Empty;
else else
return arr->Get(arr->GetLength() - 1); return arr->Get(arr->GetLength() - 1);
} }

View File

@ -38,7 +38,7 @@ class I2_REMOTE_API HttpUtility
public: public:
static Dictionary::Ptr FetchRequestParameters(HttpRequest& request); static Dictionary::Ptr FetchRequestParameters(HttpRequest& request);
static void SendJsonBody(HttpResponse& response, const Value& val); static void SendJsonBody(HttpResponse& response, const Value& val);
static String GetLastParameter(const Dictionary::Ptr& params, const String& key); static Value GetLastParameter(const Dictionary::Ptr& params, const String& key);
}; };
} }