diff --git a/doc/9-icinga2-api.md b/doc/9-icinga2-api.md index 4869e94b6..a4da66a5f 100644 --- a/doc/9-icinga2-api.md +++ b/doc/9-icinga2-api.md @@ -657,6 +657,32 @@ URL path when querying a single object: The result set contains the type and name of the template. +## Variables + +Provides methods to manage global variables: + +* [querying variables](9-icinga2-api.md#icinga2-api-variables-query) + +### Querying Variables + +You can request information about global variables by sending +a `GET` query to the `/v1/variables/` URL endpoint: + + $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables' + +A [filter](9-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The +variable information object can be accessed in the filter using the `variable` variable: + + $ curl -u root:root -k 'https://localhost:5661/v1/variables' -H "Accept: application/json" -X PUT -H "X-HTTP-Method-Override: GET" \ + -d '{ "filter": "variable.type in [ \"String\", \"Number\" ]" }' + +Instead of using a filter you can optionally specify the variable name in the +URL path when querying a single variable: + + $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables/PrefixDir' + +The result set contains the type, name and value of the global variable. + ## Actions There are several actions available for Icinga 2 provided by the `/v1/actions` diff --git a/lib/remote/CMakeLists.txt b/lib/remote/CMakeLists.txt index 521186c83..dd8a215cf 100644 --- a/lib/remote/CMakeLists.txt +++ b/lib/remote/CMakeLists.txt @@ -30,7 +30,7 @@ set(remote_SOURCES httpchunkedencoding.cpp httpclientconnection.cpp httpserverconnection.cpp httphandler.cpp httprequest.cpp httpresponse.cpp httputility.cpp infohandler.cpp jsonrpc.cpp jsonrpcconnection.cpp jsonrpcconnection-heartbeat.cpp messageorigin.cpp modifyobjecthandler.cpp statushandler.cpp objectqueryhandler.cpp templatequeryhandler.cpp - typequeryhandler.cpp url.cpp zone.cpp zone.thpp + typequeryhandler.cpp url.cpp variablequeryhandler.cpp zone.cpp zone.thpp ) if(ICINGA2_UNITY_BUILD) diff --git a/lib/remote/variablequeryhandler.cpp b/lib/remote/variablequeryhandler.cpp new file mode 100644 index 000000000..33888b6c5 --- /dev/null +++ b/lib/remote/variablequeryhandler.cpp @@ -0,0 +1,124 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2016 Icinga Development Team (https://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/variablequeryhandler.hpp" +#include "remote/httputility.hpp" +#include "remote/filterutility.hpp" +#include "base/configtype.hpp" +#include "base/scriptglobal.hpp" +#include "base/logger.hpp" +#include "base/serializer.hpp" +#include +#include + +using namespace icinga; + +REGISTER_URLHANDLER("/v1/variables", VariableQueryHandler); + +class VariableTargetProvider : public TargetProvider +{ +public: + DECLARE_PTR_TYPEDEFS(VariableTargetProvider); + + static Dictionary::Ptr GetTargetForVar(const String& name, const Value& value) + { + Dictionary::Ptr target = new Dictionary(); + target->Set("name", name); + target->Set("type", value.GetReflectionType()->GetName()); + target->Set("value", value); + return target; + } + + virtual void FindTargets(const String& type, + const boost::function& addTarget) const override + { + { + Dictionary::Ptr globals = ScriptGlobal::GetGlobals(); + ObjectLock olock(globals); + BOOST_FOREACH(const Dictionary::Pair& kv, globals) { + addTarget(GetTargetForVar(kv.first, kv.second)); + } + } + } + + virtual Value GetTargetByName(const String& type, const String& name) const override + { + return GetTargetForVar(name, ScriptGlobal::Get(name)); + } + + virtual bool IsValidType(const String& type) const override + { + return type == "Variable"; + } + + virtual String GetPluralName(const String& type) const override + { + return "variables"; + } +}; + +bool VariableQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params) +{ + if (request.RequestUrl->GetPath().size() > 3) + return false; + + if (request.RequestMethod != "GET") + return false; + + QueryDescription qd; + qd.Types.insert("Variable"); + qd.Provider = new VariableTargetProvider(); + + params->Set("type", "Variable"); + + if (request.RequestUrl->GetPath().size() >= 3) + params->Set("variable", request.RequestUrl->GetPath()[2]); + + std::vector objs; + + try { + objs = FilterUtility::GetFilterTargets(qd, params, user, "variable"); + } catch (const std::exception& ex) { + HttpUtility::SendJsonError(response, 404, + "No variables found.", + HttpUtility::GetLastParameter(params, "verboseErrors") ? DiagnosticInformation(ex) : ""); + return true; + } + + Array::Ptr results = new Array(); + + BOOST_FOREACH(const Dictionary::Ptr& var, objs) { + Dictionary::Ptr result1 = new Dictionary(); + results->Add(result1); + + Dictionary::Ptr resultAttrs = new Dictionary(); + result1->Set("name", var->Get("name")); + result1->Set("type", var->Get("type")); + result1->Set("value", Serialize(var->Get("value"), 0)); + } + + Dictionary::Ptr result = new Dictionary(); + result->Set("results", results); + + response.SetStatus(200, "OK"); + HttpUtility::SendJsonBody(response, result); + + return true; +} + diff --git a/lib/remote/variablequeryhandler.hpp b/lib/remote/variablequeryhandler.hpp new file mode 100644 index 000000000..6feca4060 --- /dev/null +++ b/lib/remote/variablequeryhandler.hpp @@ -0,0 +1,39 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2016 Icinga Development Team (https://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 VARIABLEQUERYHANDLER_H +#define VARIABLEQUERYHANDLER_H + +#include "remote/httphandler.hpp" + +namespace icinga +{ + +class I2_REMOTE_API VariableQueryHandler : public HttpHandler +{ +public: + DECLARE_PTR_TYPEDEFS(VariableQueryHandler); + + virtual bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, + HttpResponse& response, const Dictionary::Ptr& params) override; +}; + +} + +#endif /* VARIABLEQUERYHANDLER_H */