]> granicus.if.org Git - icinga2/commitdiff
Implement support for modified attributes in the API
authorGunnar Beutner <gunnar@beutner.name>
Wed, 12 Aug 2015 12:15:01 +0000 (14:15 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Sat, 15 Aug 2015 18:07:11 +0000 (20:07 +0200)
refs #9081

lib/base/scriptutils.cpp
lib/base/scriptutils.hpp
lib/icinga/icingaapplication.cpp
lib/remote/CMakeLists.txt
lib/remote/modifyobjecthandler.cpp [new file with mode: 0644]
lib/remote/modifyobjecthandler.hpp [new file with mode: 0644]
lib/remote/statusqueryhandler.cpp

index 6028380a846502d19e482fe4028a8a4a94bb69b7..edd58c858ec7adb02ba1396450af276aec113170 100644 (file)
@@ -251,12 +251,19 @@ Array::Ptr ScriptUtils::Keys(const Dictionary::Ptr& dict)
        return result;
 }
 
-DynamicObject::Ptr ScriptUtils::GetObject(const Type::Ptr& type, const String& name)
+DynamicObject::Ptr ScriptUtils::GetObject(const Value& vtype, const String& name)
 {
-       DynamicType::Ptr dtype = DynamicType::GetByName(type->GetName());
+       String typeName;
+
+       if (vtype.IsObjectType<Type>())
+               typeName = static_cast<Type::Ptr>(vtype)->GetName();
+       else
+               typeName = vtype;
+
+       DynamicType::Ptr dtype = DynamicType::GetByName(typeName);
 
        if (!dtype)
-               BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type name"));
+               return DynamicObject::Ptr();
 
        return dtype->GetObject(name);
 }
index 9005d8bcb12bc6998f5b6cb315f86766f37d64c2..ff36327bc76ea89732cb130611477cf2980bdd8f 100644 (file)
@@ -47,7 +47,7 @@ public:
        static Array::Ptr Range(const std::vector<Value>& arguments);
        static Type::Ptr TypeOf(const Value& value);
        static Array::Ptr Keys(const Dictionary::Ptr& dict);
-       static DynamicObject::Ptr GetObject(const Type::Ptr& type, const String& name);
+       static DynamicObject::Ptr GetObject(const Value& type, const String& name);
        static Array::Ptr GetObjects(const Type::Ptr& type);
        static void Assert(const Value& arg);
        static String MsiGetComponentPathShim(const String& component);
index 1b811c607602d21749d293241e3d668212eae8f7..c4f6fee6fa5e668088b1b1afdd659addf42f4d3f 100644 (file)
@@ -140,13 +140,14 @@ static void PersistModAttrHelper(const ConfigWriter::Ptr& cw, DynamicObject::Ptr
                if (previousObject)
                        cw->EmitRaw("}\n\n");
 
-               cw->EmitRaw("var obj = get_object(");
-               cw->EmitIdentifier(object->GetReflectionType()->GetName(), 0);
-               cw->EmitRaw(", ");
-               cw->EmitString(object->GetName());
-               cw->EmitRaw(")\n");
+               cw->EmitRaw("var obj = ");
 
-               cw->EmitRaw("if (obj) {\n");
+               Array::Ptr args1 = new Array();
+               args1->Add(object->GetReflectionType()->GetName());
+               args1->Add(object->GetName());
+               cw->EmitFunctionCall("get_object", args1);
+
+               cw->EmitRaw("\nif (obj) {\n");
        }
 
        cw->EmitRaw("\tobj.");
index 07a9953f264470ccac8ec9a9194fc578b81676e4..68c82b18218285910a24b70ae2a2ab3262800c8b 100644 (file)
@@ -28,7 +28,7 @@ set(remote_SOURCES
   endpoint.cpp endpoint.thpp filterutility.cpp
   httpchunkedencoding.cpp  httpconnection.cpp httphandler.cpp httprequest.cpp httpresponse.cpp
   httputility.cpp jsonrpc.cpp jsonrpcconnection.cpp jsonrpcconnection-heartbeat.cpp
-  messageorigin.cpp statusqueryhandler.cpp url.cpp zone.cpp zone.thpp
+  messageorigin.cpp modifyobjecthandler.cpp statusqueryhandler.cpp url.cpp zone.cpp zone.thpp
 )
 
 if(ICINGA2_UNITY_BUILD)
diff --git a/lib/remote/modifyobjecthandler.cpp b/lib/remote/modifyobjecthandler.cpp
new file mode 100644 (file)
index 0000000..6b66be3
--- /dev/null
@@ -0,0 +1,100 @@
+/******************************************************************************
+ * 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/modifyobjecthandler.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", ModifyObjectHandler);
+
+bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
+{
+       if (request.RequestMethod != "POST")
+               return false;
+
+       if (request.RequestUrl->GetPath().size() < 2)
+               return false;
+
+       Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[1]);
+
+       if (!type)
+               return false;
+
+       QueryDescription qd;
+       qd.Types.insert(type);
+
+       Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
+
+       params->Set("type", type->GetName());
+
+       if (request.RequestUrl->GetPath().size() >= 3) {
+               String attr = type->GetName();
+               boost::algorithm::to_lower(attr);
+               params->Set(attr, request.RequestUrl->GetPath()[2]);
+       }
+
+       std::vector<DynamicObject::Ptr> objs = FilterUtility::GetFilterTargets(qd, params);
+
+       Dictionary::Ptr attrs = params->Get("attrs");
+
+       Array::Ptr results = new Array();
+
+       if (attrs) {
+               BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) {
+                       Dictionary::Ptr result1 = new Dictionary();
+
+                       result1->Set("type", obj->GetReflectionType()->GetName());
+                       result1->Set("name", obj->GetName());
+
+                       String key;
+
+                       try {
+                               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);
+               }
+       }
+
+       Dictionary::Ptr result = new Dictionary();
+       result->Set("results", results);
+
+       response.SetStatus(200, "OK");
+       HttpUtility::SendJsonBody(response, result);
+
+       return true;
+}
+
diff --git a/lib/remote/modifyobjecthandler.hpp b/lib/remote/modifyobjecthandler.hpp
new file mode 100644 (file)
index 0000000..da424b9
--- /dev/null
@@ -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 MODIFYOBJECTHANDLER_H
+#define MODIFYOBJECTHANDLER_H
+
+#include "remote/httphandler.hpp"
+
+namespace icinga
+{
+
+class I2_REMOTE_API ModifyObjectHandler : public HttpHandler
+{
+public:
+       DECLARE_PTR_TYPEDEFS(ModifyObjectHandler);
+
+       virtual bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response);
+};
+
+}
+
+#endif /* MODIFYOBJECTHANDLER_H */
index d66d362401ca2b59d4939341dbaec51d9bb1f534..8e0773cdee20f517c33eec6bd0ab768cf10b6591 100644 (file)
@@ -30,6 +30,9 @@ REGISTER_URLHANDLER("/v1", StatusQueryHandler);
 
 bool StatusQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
 {
+       if (request.RequestMethod != "GET")
+               return false;
+
        if (request.RequestUrl->GetPath().size() < 2)
                return false;