From: Gunnar Beutner Date: Wed, 12 Aug 2015 13:27:35 +0000 (+0200) Subject: Implement support for creating objects X-Git-Tag: v2.4.0~421 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16ddc12c0680b6e4a1b081e0a218a56fbe205fdd;p=icinga2 Implement support for creating objects refs #9101 --- diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 373ced031..d0e02e9c2 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -46,7 +46,7 @@ ConfigItem::TypeMap ConfigItem::m_Items; ConfigItem::ItemList ConfigItem::m_UnnamedItems; ConfigItem::ItemList ConfigItem::m_CommittedItems; -REGISTER_SCRIPTFUNCTION(commit_objects, &ConfigItem::ScriptCommit); +REGISTER_SCRIPTFUNCTION(commit_objects, &ConfigItem::CommitAndActivate); /** * Constructor for the ConfigItem class. @@ -477,7 +477,7 @@ bool ConfigItem::ActivateItems(void) return true; } -bool ConfigItem::ScriptCommit(void) +bool ConfigItem::CommitAndActivate(void) { WorkQueue upq(25000, Application::GetConcurrency()); @@ -497,10 +497,10 @@ bool ConfigItem::ScriptCommit(void) continue; #ifdef I2_DEBUG - Log(LogDebug, "ConfigItem") - << "Activating object '" << object->GetName() << "' of type '" << object->GetType()->GetName() << "'"; + Log(LogDebug, "ConfigItem") + << "Activating object '" << object->GetName() << "' of type '" << object->GetType()->GetName() << "'"; #endif /* I2_DEBUG */ - upq.Enqueue(boost::bind(&DynamicObject::Activate, object)); + upq.Enqueue(boost::bind(&DynamicObject::Activate, object)); } } diff --git a/lib/config/configitem.hpp b/lib/config/configitem.hpp index 7bf413f94..4b0309224 100644 --- a/lib/config/configitem.hpp +++ b/lib/config/configitem.hpp @@ -67,7 +67,7 @@ public: static bool CommitItems(void); static bool ActivateItems(void); - static bool ScriptCommit(void); + static bool CommitAndActivate(void); static std::vector GetItems(const String& type); diff --git a/lib/remote/CMakeLists.txt b/lib/remote/CMakeLists.txt index 68c82b182..6791bd12e 100644 --- a/lib/remote/CMakeLists.txt +++ b/lib/remote/CMakeLists.txt @@ -23,7 +23,7 @@ mkclass_target(zone.ti zone.tcpp zone.thpp) set(remote_SOURCES actionshandler.cpp apiaction.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 endpoint.cpp endpoint.thpp filterutility.cpp httpchunkedencoding.cpp httpconnection.cpp httphandler.cpp httprequest.cpp httpresponse.cpp diff --git a/lib/remote/createobjecthandler.cpp b/lib/remote/createobjecthandler.cpp new file mode 100644 index 000000000..d535a5e42 --- /dev/null +++ b/lib/remote/createobjecthandler.cpp @@ -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 +#include + +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; +} + diff --git a/lib/remote/createobjecthandler.hpp b/lib/remote/createobjecthandler.hpp new file mode 100644 index 000000000..9510b6777 --- /dev/null +++ b/lib/remote/createobjecthandler.hpp @@ -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 */ diff --git a/lib/remote/modifyobjecthandler.cpp b/lib/remote/modifyobjecthandler.cpp index 6b66be3ad..842a30a96 100644 --- a/lib/remote/modifyobjecthandler.cpp +++ b/lib/remote/modifyobjecthandler.cpp @@ -62,31 +62,31 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r Array::Ptr results = new Array(); - if (attrs) { - BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) { - Dictionary::Ptr result1 = new Dictionary(); + BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) { + Dictionary::Ptr result1 = new Dictionary(); - result1->Set("type", obj->GetReflectionType()->GetName()); - result1->Set("name", obj->GetName()); + result1->Set("type", obj->GetReflectionType()->GetName()); + result1->Set("name", obj->GetName()); - String key; + String key; - try { + try { + if (attrs) { ObjectLock olock(attrs); BOOST_FOREACH(const Dictionary::Pair& kv, attrs) { key = kv.first; 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();