mirror of
https://github.com/Icinga/icinga2.git
synced 2025-04-07 20:25:08 +02:00
parent
f405a26052
commit
e2290d5012
@ -177,6 +177,14 @@ void DynamicObject::Register(void)
|
||||
dtype->RegisterObject(this);
|
||||
}
|
||||
|
||||
void DynamicObject::Unregister(void)
|
||||
{
|
||||
ASSERT(!OwnsLock());
|
||||
|
||||
DynamicType::Ptr dtype = GetType();
|
||||
dtype->UnregisterObject(this);
|
||||
}
|
||||
|
||||
void DynamicObject::Start(void)
|
||||
{
|
||||
ASSERT(!OwnsLock());
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
bool IsAttributeModified(const String& attr) const;
|
||||
|
||||
void Register(void);
|
||||
void Unregister(void);
|
||||
|
||||
void Activate(void);
|
||||
void Deactivate(void);
|
||||
|
@ -34,6 +34,7 @@ enum HAMode
|
||||
class NameComposer {
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const = 0;
|
||||
virtual Dictionary::Ptr ParseName(const String& name) const = 0;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
@ -113,6 +113,18 @@ void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicType::UnregisterObject(const DynamicObject::Ptr& object)
|
||||
{
|
||||
String name = object->GetName();
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_ObjectMap.erase(name);
|
||||
m_ObjectVector.erase(std::remove(m_ObjectVector.begin(), m_ObjectVector.end(), object), m_ObjectVector.end());
|
||||
}
|
||||
}
|
||||
|
||||
DynamicObject::Ptr DynamicType::GetObject(const String& name) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
DynamicObject::Ptr GetObject(const String& name) const;
|
||||
|
||||
void RegisterObject(const DynamicObject::Ptr& object);
|
||||
void UnregisterObject(const DynamicObject::Ptr& object);
|
||||
|
||||
static std::vector<DynamicType::Ptr> GetTypes(void);
|
||||
std::pair<DynamicTypeIterator<DynamicObject>, DynamicTypeIterator<DynamicObject> > GetObjects(void);
|
||||
|
@ -56,6 +56,16 @@ Type::Ptr Type::GetByName(const String& name)
|
||||
return ptype;
|
||||
}
|
||||
|
||||
String Type::GetPluralName(void) const
|
||||
{
|
||||
String name = GetName();
|
||||
|
||||
if (name[name.GetLength() - 1] == 'y')
|
||||
return name.SubStr(0, name.GetLength() - 1) + "ies";
|
||||
else
|
||||
return name + "s";
|
||||
}
|
||||
|
||||
Object::Ptr Type::Instantiate(void) const
|
||||
{
|
||||
ObjectFactory factory = GetFactory();
|
||||
|
@ -80,6 +80,8 @@ public:
|
||||
virtual Field GetFieldInfo(int id) const = 0;
|
||||
virtual int GetFieldCount(void) const = 0;
|
||||
|
||||
String GetPluralName(void) const;
|
||||
|
||||
Object::Ptr Instantiate(void) const;
|
||||
|
||||
bool IsAssignableFrom(const Type::Ptr& other) const;
|
||||
|
@ -258,10 +258,14 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
|
||||
}
|
||||
}
|
||||
|
||||
// activate config only after daemonization: it starts threads and that is not compatible with fork()
|
||||
if (!ConfigItem::ActivateItems()) {
|
||||
Log(LogCritical, "cli", "Error activating configuration.");
|
||||
return EXIT_FAILURE;
|
||||
{
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
|
||||
// activate config only after daemonization: it starts threads and that is not compatible with fork()
|
||||
if (!ConfigItem::ActivateItems(upq, true)) {
|
||||
Log(LogCritical, "cli", "Error activating configuration.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm.count("daemonize")) {
|
||||
|
@ -123,7 +123,8 @@ bool DaemonUtility::LoadConfigFiles(const std::vector<std::string>& configs,
|
||||
if (!DaemonUtility::ValidateConfigFiles(configs, objectsFile))
|
||||
return false;
|
||||
|
||||
bool result = ConfigItem::CommitItems();
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
bool result = ConfigItem::CommitItems(upq);
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
@ -268,6 +268,19 @@ void ConfigItem::Register(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the configuration item.
|
||||
*/
|
||||
void ConfigItem::Unregister(void)
|
||||
{
|
||||
if (m_Object)
|
||||
m_Object->Unregister();
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_UnnamedItems.erase(std::remove(m_UnnamedItems.begin(), m_UnnamedItems.end(), this), m_UnnamedItems.end());
|
||||
m_Items[m_Type].erase(m_Name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a configuration item by type and name.
|
||||
*
|
||||
@ -292,7 +305,7 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
||||
return it2->second;
|
||||
}
|
||||
|
||||
bool ConfigItem::CommitNewItems(WorkQueue& upq)
|
||||
bool ConfigItem::CommitNewItems(WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems)
|
||||
{
|
||||
typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
|
||||
std::vector<ItemPair> items;
|
||||
@ -320,6 +333,7 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq)
|
||||
return true;
|
||||
|
||||
BOOST_FOREACH(const ItemPair& ip, items) {
|
||||
newItems.push_back(ip.first);
|
||||
upq.Enqueue(boost::bind(&ConfigItem::Commit, ip.first, ip.second));
|
||||
}
|
||||
|
||||
@ -398,7 +412,7 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq)
|
||||
if (upq.HasExceptions())
|
||||
return false;
|
||||
|
||||
if (!CommitNewItems(upq))
|
||||
if (!CommitNewItems(upq, newItems))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -406,44 +420,53 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigItem::CommitItems(void)
|
||||
bool ConfigItem::CommitItems(WorkQueue& upq)
|
||||
{
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Committing config items");
|
||||
|
||||
if (!CommitNewItems(upq)) {
|
||||
std::vector<ConfigItem::Ptr> newItems;
|
||||
|
||||
if (!CommitNewItems(upq, newItems)) {
|
||||
upq.ReportExceptions("config");
|
||||
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& item, newItems) {
|
||||
item->Unregister();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ApplyRule::CheckMatches();
|
||||
|
||||
/* log stats for external parsers */
|
||||
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
||||
int count = std::distance(type->GetObjects().first, type->GetObjects().second);
|
||||
if (count > 0)
|
||||
Log(LogInformation, "ConfigItem")
|
||||
<< "Checked " << count << " " << type->GetName() << "(s).";
|
||||
typedef std::map<Type::Ptr, int> ItemCountMap;
|
||||
ItemCountMap itemCounts;
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& item, newItems) {
|
||||
itemCounts[item->m_Object->GetReflectionType()]++;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const ItemCountMap::value_type& kv, itemCounts) {
|
||||
Log(LogInformation, "ConfigItem")
|
||||
<< "Instantiated " << kv.second << " " << kv.first->GetPluralName() << ".";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigItem::ActivateItems(void)
|
||||
bool ConfigItem::ActivateItems(WorkQueue& upq, bool restoreState)
|
||||
{
|
||||
/* restore the previous program state */
|
||||
try {
|
||||
DynamicObject::RestoreObjects(Application::GetStatePath());
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogCritical, "ConfigItem")
|
||||
<< "Failed to restore state file: " << DiagnosticInformation(ex);
|
||||
if (restoreState) {
|
||||
/* restore the previous program state */
|
||||
try {
|
||||
DynamicObject::RestoreObjects(Application::GetStatePath());
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogCritical, "ConfigItem")
|
||||
<< "Failed to restore state file: " << DiagnosticInformation(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Triggering Start signal for config items");
|
||||
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
|
||||
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
|
||||
if (object->IsActive())
|
||||
@ -481,40 +504,11 @@ bool ConfigItem::CommitAndActivate(void)
|
||||
{
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
|
||||
if (!CommitNewItems(upq)) {
|
||||
upq.ReportExceptions("ConfigItem");
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_Items.clear();
|
||||
m_UnnamedItems.clear();
|
||||
|
||||
if (!CommitItems(upq))
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
|
||||
if (object->IsActive())
|
||||
continue;
|
||||
|
||||
#ifdef I2_DEBUG
|
||||
Log(LogDebug, "ConfigItem")
|
||||
<< "Activating object '" << object->GetName() << "' of type '" << object->GetType()->GetName() << "'";
|
||||
#endif /* I2_DEBUG */
|
||||
upq.Enqueue(boost::bind(&DynamicObject::Activate, object));
|
||||
}
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
|
||||
if (upq.HasExceptions()) {
|
||||
upq.ReportExceptions("ConfigItem");
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_Items.clear();
|
||||
m_UnnamedItems.clear();
|
||||
|
||||
if (!ActivateItems(upq, false))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
|
||||
DynamicObject::Ptr Commit(bool discard = true);
|
||||
void Register(void);
|
||||
void Unregister(void);
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
Dictionary::Ptr GetScope(void) const;
|
||||
@ -64,8 +65,8 @@ public:
|
||||
static ConfigItem::Ptr GetObject(const String& type,
|
||||
const String& name);
|
||||
|
||||
static bool CommitItems(void);
|
||||
static bool ActivateItems(void);
|
||||
static bool CommitItems(WorkQueue& upq);
|
||||
static bool ActivateItems(WorkQueue& upq, bool restoreState);
|
||||
|
||||
static bool CommitAndActivate(void);
|
||||
|
||||
@ -97,7 +98,7 @@ private:
|
||||
static ConfigItem::Ptr GetObjectUnlocked(const String& type,
|
||||
const String& name);
|
||||
|
||||
static bool CommitNewItems(WorkQueue& upq);
|
||||
static bool CommitNewItems(WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "base/logger.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -45,6 +47,27 @@ String DependencyNameComposer::MakeName(const String& shortName, const Object::P
|
||||
return name;
|
||||
}
|
||||
|
||||
Dictionary::Ptr DependencyNameComposer::ParseName(const String& name) const
|
||||
{
|
||||
std::vector<String> tokens;
|
||||
boost::algorithm::split(tokens, name, boost::is_any_of("!"));
|
||||
|
||||
if (tokens.size() < 2)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Dependency name."));
|
||||
|
||||
Dictionary::Ptr result = new Dictionary();
|
||||
result->Set("child_host_name", tokens[0]);
|
||||
|
||||
if (tokens.size() > 2) {
|
||||
result->Set("child_service_name", tokens[1]);
|
||||
result->Set("name", tokens[2]);
|
||||
} else {
|
||||
result->Set("name", tokens[1]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Dependency::OnConfigLoaded(void)
|
||||
{
|
||||
Value defaultFilter;
|
||||
|
@ -30,6 +30,7 @@ class I2_ICINGA_API DependencyNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
virtual Dictionary::Ptr ParseName(const String& name) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "base/initialize.hpp"
|
||||
#include "base/scriptglobal.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -54,6 +56,27 @@ String NotificationNameComposer::MakeName(const String& shortName, const Object:
|
||||
return name;
|
||||
}
|
||||
|
||||
Dictionary::Ptr NotificationNameComposer::ParseName(const String& name) const
|
||||
{
|
||||
std::vector<String> tokens;
|
||||
boost::algorithm::split(tokens, name, boost::is_any_of("!"));
|
||||
|
||||
if (tokens.size() < 2)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Notification name."));
|
||||
|
||||
Dictionary::Ptr result = new Dictionary();
|
||||
result->Set("host_name", tokens[0]);
|
||||
|
||||
if (tokens.size() > 2) {
|
||||
result->Set("service_name", tokens[1]);
|
||||
result->Set("name", tokens[2]);
|
||||
} else {
|
||||
result->Set("name", tokens[1]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Notification::StaticInitialize(void)
|
||||
{
|
||||
ScriptGlobal::Set("OK", StateFilterOK);
|
||||
|
@ -29,6 +29,7 @@ class I2_ICINGA_API NotificationNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
virtual Dictionary::Ptr ParseName(const String& name) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "base/logger.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -57,6 +59,27 @@ String ScheduledDowntimeNameComposer::MakeName(const String& shortName, const Ob
|
||||
return name;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ScheduledDowntimeNameComposer::ParseName(const String& name) const
|
||||
{
|
||||
std::vector<String> tokens;
|
||||
boost::algorithm::split(tokens, name, boost::is_any_of("!"));
|
||||
|
||||
if (tokens.size() < 2)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid ScheduledDowntime name."));
|
||||
|
||||
Dictionary::Ptr result = new Dictionary();
|
||||
result->Set("host_name", tokens[0]);
|
||||
|
||||
if (tokens.size() > 2) {
|
||||
result->Set("service_name", tokens[1]);
|
||||
result->Set("name", tokens[2]);
|
||||
} else {
|
||||
result->Set("name", tokens[1]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ScheduledDowntime::StaticInitialize(void)
|
||||
{
|
||||
l_Timer = new Timer();
|
||||
|
@ -29,6 +29,7 @@ class I2_ICINGA_API ScheduledDowntimeNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
virtual Dictionary::Ptr ParseName(const String& name) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "base/utility.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/bind/apply.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -42,6 +44,21 @@ String ServiceNameComposer::MakeName(const String& shortName, const Object::Ptr&
|
||||
return service->GetHostName() + "!" + shortName;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ServiceNameComposer::ParseName(const String& name) const
|
||||
{
|
||||
std::vector<String> tokens;
|
||||
boost::algorithm::split(tokens, name, boost::is_any_of("!"));
|
||||
|
||||
if (tokens.size() < 2)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Service name."));
|
||||
|
||||
Dictionary::Ptr result = new Dictionary();
|
||||
result->Set("host_name", tokens[0]);
|
||||
result->Set("name", tokens[1]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Service::OnAllConfigLoaded(void)
|
||||
{
|
||||
Checkable::OnAllConfigLoaded();
|
||||
|
@ -32,6 +32,7 @@ class I2_ICINGA_API ServiceNameComposer : public NameComposer
|
||||
{
|
||||
public:
|
||||
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||
virtual Dictionary::Ptr ParseName(const String& name) const;
|
||||
};
|
||||
}}}
|
||||
|
||||
|
@ -23,8 +23,8 @@ 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 createobjecthandler.cpp configfileshandler.cpp
|
||||
configmoduleshandler.cpp configmoduleutility.cpp configstageshandler.cpp
|
||||
apiuser.cpp apiuser.thpp authority.cpp base64.cpp createobjecthandler.cpp deleteobjecthandler.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
|
||||
httputility.cpp jsonrpc.cpp jsonrpcconnection.cpp jsonrpcconnection-heartbeat.cpp
|
||||
|
@ -47,6 +47,14 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
||||
|
||||
String name = request.RequestUrl->GetPath()[2];
|
||||
|
||||
NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
|
||||
Dictionary::Ptr nameParts;
|
||||
|
||||
if (nc) {
|
||||
nameParts = nc->ParseName(name);
|
||||
name = nameParts->Get("name");
|
||||
}
|
||||
|
||||
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
|
||||
|
||||
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder();
|
||||
@ -64,6 +72,14 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
||||
}
|
||||
}
|
||||
|
||||
if (nameParts) {
|
||||
ObjectLock olock(nameParts);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, nameParts) {
|
||||
SetExpression *expr = new SetExpression(MakeIndexer(ScopeThis, kv.first), OpSetLiteral, MakeLiteral(kv.second));
|
||||
builder->AddExpression(expr);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary::Ptr attrs = params->Get("attrs");
|
||||
|
||||
if (attrs) {
|
||||
@ -77,11 +93,28 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
||||
ConfigItem::Ptr item = builder->Compile();
|
||||
item->Register();
|
||||
|
||||
ConfigItem::CommitAndActivate();
|
||||
WorkQueue upq;
|
||||
|
||||
Dictionary::Ptr result1 = new Dictionary();
|
||||
result1->Set("code", 200);
|
||||
result1->Set("status", "Object created.");
|
||||
int code;
|
||||
String status;
|
||||
|
||||
if (!ConfigItem::CommitItems(upq) || !ConfigItem::ActivateItems(upq, false)) {
|
||||
code = 500;
|
||||
status = "Object could not be created.";
|
||||
|
||||
Array::Ptr errors = new Array();
|
||||
BOOST_FOREACH(const boost::exception_ptr& ex, upq.GetExceptions()) {
|
||||
errors->Add(DiagnosticInformation(ex));
|
||||
}
|
||||
result1->Set("errors", errors);
|
||||
} else {
|
||||
code = 200;
|
||||
status = "Object created";
|
||||
}
|
||||
|
||||
result1->Set("code", code);
|
||||
result1->Set("status", status);
|
||||
|
||||
Array::Ptr results = new Array();
|
||||
results->Add(result1);
|
||||
@ -89,7 +122,7 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
||||
Dictionary::Ptr result = new Dictionary();
|
||||
result->Set("results", results);
|
||||
|
||||
response.SetStatus(200, "OK");
|
||||
response.SetStatus(code, status);
|
||||
HttpUtility::SendJsonBody(response, result);
|
||||
|
||||
return true;
|
||||
|
97
lib/remote/deleteobjecthandler.cpp
Normal file
97
lib/remote/deleteobjecthandler.cpp
Normal 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/deleteobjecthandler.hpp"
|
||||
#include "remote/httputility.hpp"
|
||||
#include "remote/filterutility.hpp"
|
||||
#include "remote/apiaction.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", DeleteObjectHandler);
|
||||
|
||||
bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
if (request.RequestMethod != "DELETE")
|
||||
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);
|
||||
|
||||
Array::Ptr results = new Array();
|
||||
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) {
|
||||
Dictionary::Ptr result1 = new Dictionary();
|
||||
result1->Set("type", type->GetName());
|
||||
result1->Set("name", obj->GetName());
|
||||
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject(type->GetName(), obj->GetName());
|
||||
|
||||
try {
|
||||
obj->Deactivate();
|
||||
|
||||
if (item)
|
||||
item->Unregister();
|
||||
else
|
||||
obj->Unregister();
|
||||
|
||||
result1->Set("code", 200);
|
||||
result1->Set("status", "Object was deleted.");
|
||||
} catch (const std::exception& ex) {
|
||||
result1->Set("code", 500);
|
||||
result1->Set("status", "Object could not be deleted: " + DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
results->Add(result1);
|
||||
}
|
||||
|
||||
Dictionary::Ptr result = new Dictionary();
|
||||
result->Set("results", results);
|
||||
|
||||
response.SetStatus(200, "OK");
|
||||
HttpUtility::SendJsonBody(response, result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
38
lib/remote/deleteobjecthandler.hpp
Normal file
38
lib/remote/deleteobjecthandler.hpp
Normal 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 DELETEOBJECTHANDLER_H
|
||||
#define DELETEOBJECTHANDLER_H
|
||||
|
||||
#include "remote/httphandler.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class I2_REMOTE_API DeleteObjectHandler : public HttpHandler
|
||||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(DeleteObjectHandler);
|
||||
|
||||
virtual bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* DELETEOBJECTHANDLER_H */
|
@ -38,7 +38,7 @@ Type::Ptr FilterUtility::TypeFromPluralName(const String& pluralName)
|
||||
Type::Ptr type = Type::GetByName(dtype->GetName());
|
||||
ASSERT(type);
|
||||
|
||||
String pname = GetPluralName(type);
|
||||
String pname = type->GetPluralName();
|
||||
boost::algorithm::to_lower(pname);
|
||||
|
||||
if (uname == pname)
|
||||
@ -48,16 +48,6 @@ Type::Ptr FilterUtility::TypeFromPluralName(const String& pluralName)
|
||||
return Type::Ptr();
|
||||
}
|
||||
|
||||
String FilterUtility::GetPluralName(const Type::Ptr& type)
|
||||
{
|
||||
String name = type->GetName();
|
||||
|
||||
if (name[name.GetLength() - 1] == 'y')
|
||||
return name.SubStr(0, name.GetLength() - 1) + "ies";
|
||||
else
|
||||
return name + "s";
|
||||
}
|
||||
|
||||
DynamicObject::Ptr FilterUtility::GetObjectByTypeAndName(const String& type, const String& name)
|
||||
{
|
||||
DynamicType::Ptr dtype = DynamicType::GetByName(type);
|
||||
@ -82,7 +72,7 @@ std::vector<DynamicObject::Ptr> FilterUtility::GetFilterTargets(const QueryDescr
|
||||
result.push_back(obj);
|
||||
}
|
||||
|
||||
attr = GetPluralName(type);
|
||||
attr = type->GetPluralName();
|
||||
boost::algorithm::to_lower(attr);
|
||||
|
||||
if (query->Contains(attr)) {
|
||||
|
@ -41,7 +41,6 @@ struct QueryDescription
|
||||
class I2_REMOTE_API FilterUtility
|
||||
{
|
||||
public:
|
||||
static String GetPluralName(const Type::Ptr& type);
|
||||
static Type::Ptr TypeFromPluralName(const String& pluralName);
|
||||
static DynamicObject::Ptr GetObjectByTypeAndName(const String& type, const String& name);
|
||||
static std::vector<DynamicObject::Ptr> GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query);
|
||||
|
@ -65,7 +65,7 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) {
|
||||
Dictionary::Ptr result1 = new Dictionary();
|
||||
|
||||
result1->Set("type", obj->GetReflectionType()->GetName());
|
||||
result1->Set("type", type->GetName());
|
||||
result1->Set("name", obj->GetName());
|
||||
|
||||
String key;
|
||||
|
@ -87,7 +87,8 @@ struct GlobalConfigFixture {
|
||||
DaemonUtility::LoadConfigFiles(configs, "icinga2.debug", "icinga2.vars");
|
||||
|
||||
/* ignore config errors */
|
||||
ConfigItem::ActivateItems();
|
||||
WorkQueue upq;
|
||||
ConfigItem::ActivateItems(upq, false);
|
||||
}
|
||||
|
||||
~GlobalConfigFixture()
|
||||
|
Loading…
x
Reference in New Issue
Block a user