Implement support for creating objects

refs #9101
This commit is contained in:
Gunnar Beutner 2015-08-12 15:27:35 +02:00
parent 3d78870339
commit 16ddc12c06
6 changed files with 156 additions and 21 deletions

View File

@ -46,7 +46,7 @@ ConfigItem::TypeMap ConfigItem::m_Items;
ConfigItem::ItemList ConfigItem::m_UnnamedItems; ConfigItem::ItemList ConfigItem::m_UnnamedItems;
ConfigItem::ItemList ConfigItem::m_CommittedItems; ConfigItem::ItemList ConfigItem::m_CommittedItems;
REGISTER_SCRIPTFUNCTION(commit_objects, &ConfigItem::ScriptCommit); REGISTER_SCRIPTFUNCTION(commit_objects, &ConfigItem::CommitAndActivate);
/** /**
* Constructor for the ConfigItem class. * Constructor for the ConfigItem class.
@ -477,7 +477,7 @@ bool ConfigItem::ActivateItems(void)
return true; return true;
} }
bool ConfigItem::ScriptCommit(void) bool ConfigItem::CommitAndActivate(void)
{ {
WorkQueue upq(25000, Application::GetConcurrency()); WorkQueue upq(25000, Application::GetConcurrency());
@ -497,10 +497,10 @@ bool ConfigItem::ScriptCommit(void)
continue; continue;
#ifdef I2_DEBUG #ifdef I2_DEBUG
Log(LogDebug, "ConfigItem") Log(LogDebug, "ConfigItem")
<< "Activating object '" << object->GetName() << "' of type '" << object->GetType()->GetName() << "'"; << "Activating object '" << object->GetName() << "' of type '" << object->GetType()->GetName() << "'";
#endif /* I2_DEBUG */ #endif /* I2_DEBUG */
upq.Enqueue(boost::bind(&DynamicObject::Activate, object)); upq.Enqueue(boost::bind(&DynamicObject::Activate, object));
} }
} }

View File

@ -67,7 +67,7 @@ public:
static bool CommitItems(void); static bool CommitItems(void);
static bool ActivateItems(void); static bool ActivateItems(void);
static bool ScriptCommit(void); static bool CommitAndActivate(void);
static std::vector<ConfigItem::Ptr> GetItems(const String& type); static std::vector<ConfigItem::Ptr> GetItems(const String& type);

View File

@ -23,7 +23,7 @@ mkclass_target(zone.ti zone.tcpp zone.thpp)
set(remote_SOURCES set(remote_SOURCES
actionshandler.cpp apiaction.cpp 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 createobjecthandler.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

View File

@ -0,0 +1,97 @@
/******************************************************************************
* 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/createobjecthandler.hpp"
#include "remote/httputility.hpp"
#include "remote/filterutility.hpp"
#include "remote/apiaction.hpp"
#include "config/configitembuilder.hpp"
#include "config/configitem.hpp"
#include "base/exception.hpp"
#include "base/serializer.hpp"
#include <boost/algorithm/string.hpp>
#include <set>
using namespace icinga;
REGISTER_URLHANDLER("/v1", CreateObjectHandler);
bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
if (request.RequestMethod != "PUT")
return false;
if (request.RequestUrl->GetPath().size() < 3)
return false;
Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[1]);
if (!type)
return false;
String name = request.RequestUrl->GetPath()[2];
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder();
builder->SetType(type->GetName());
builder->SetName(name);
builder->SetScope(ScriptGlobal::GetGlobals());
Array::Ptr templates = params->Get("templates");
if (templates) {
ObjectLock olock(templates);
BOOST_FOREACH(const String& tmpl, templates) {
ImportExpression *expr = new ImportExpression(MakeLiteral(tmpl));
builder->AddExpression(expr);
}
}
Dictionary::Ptr attrs = params->Get("attrs");
if (attrs) {
ObjectLock olock(attrs);
BOOST_FOREACH(const Dictionary::Pair& kv, attrs) {
SetExpression *expr = new SetExpression(MakeIndexer(ScopeThis, kv.first), OpSetLiteral, MakeLiteral(kv.second));
builder->AddExpression(expr);
}
}
ConfigItem::Ptr item = builder->Compile();
item->Register();
ConfigItem::CommitAndActivate();
Dictionary::Ptr result1 = new Dictionary();
result1->Set("code", 200);
result1->Set("status", "Object created.");
Array::Ptr results = new Array();
results->Add(result1);
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 CREATEOBJECTHANDLER_H
#define CREATEOBJECTHANDLER_H
#include "remote/httphandler.hpp"
namespace icinga
{
class I2_REMOTE_API CreateObjectHandler : public HttpHandler
{
public:
DECLARE_PTR_TYPEDEFS(CreateObjectHandler);
virtual bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response);
};
}
#endif /* CREATEOBJECTHANDLER_H */

View File

@ -62,31 +62,31 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
Array::Ptr results = new Array(); Array::Ptr results = new Array();
if (attrs) { BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) {
BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) { Dictionary::Ptr result1 = new Dictionary();
Dictionary::Ptr result1 = new Dictionary();
result1->Set("type", obj->GetReflectionType()->GetName()); result1->Set("type", obj->GetReflectionType()->GetName());
result1->Set("name", obj->GetName()); result1->Set("name", obj->GetName());
String key; String key;
try { try {
if (attrs) {
ObjectLock olock(attrs); ObjectLock olock(attrs);
BOOST_FOREACH(const Dictionary::Pair& kv, attrs) { BOOST_FOREACH(const Dictionary::Pair& kv, attrs) {
key = kv.first; key = kv.first;
obj->ModifyAttribute(kv.first, kv.second); obj->ModifyAttribute(kv.first, kv.second);
} }
result1->Set("code", 200);
result1->Set("status", "Attributes updated.");
} catch (const std::exception& ex) {
result1->Set("code", 500);
result1->Set("status", "Attribute '" + key + "' could not be set: " + DiagnosticInformation(ex));
} }
results->Add(result1); result1->Set("code", 200);
result1->Set("status", "Attributes updated.");
} catch (const std::exception& ex) {
result1->Set("code", 500);
result1->Set("status", "Attribute '" + key + "' could not be set: " + DiagnosticInformation(ex));
} }
results->Add(result1);
} }
Dictionary::Ptr result = new Dictionary(); Dictionary::Ptr result = new Dictionary();