From 56ae875861ab260b80a030f50c4aff9f9dc8fff0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 13:32:39 +0200 Subject: Adding upstream version 2.14.2. Signed-off-by: Daniel Baumann --- lib/remote/apilistener-authority.cpp | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 lib/remote/apilistener-authority.cpp (limited to 'lib/remote/apilistener-authority.cpp') diff --git a/lib/remote/apilistener-authority.cpp b/lib/remote/apilistener-authority.cpp new file mode 100644 index 0000000..f33a190 --- /dev/null +++ b/lib/remote/apilistener-authority.cpp @@ -0,0 +1,84 @@ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ + +#include "remote/zone.hpp" +#include "remote/apilistener.hpp" +#include "base/configtype.hpp" +#include "base/utility.hpp" +#include "base/convert.hpp" + +using namespace icinga; + +std::atomic ApiListener::m_UpdatedObjectAuthority (false); + +void ApiListener::UpdateObjectAuthority() +{ + /* Always run this, even if there is no 'api' feature enabled. */ + if (auto listener = ApiListener::GetInstance()) { + Log(LogNotice, "ApiListener") + << "Updating object authority for objects at endpoint '" << listener->GetIdentity() << "'."; + } else { + Log(LogNotice, "ApiListener") + << "Updating object authority for local objects."; + } + + Zone::Ptr my_zone = Zone::GetLocalZone(); + + std::vector endpoints; + Endpoint::Ptr my_endpoint; + + if (my_zone) { + my_endpoint = Endpoint::GetLocalEndpoint(); + + int num_total = 0; + + for (const Endpoint::Ptr& endpoint : my_zone->GetEndpoints()) { + num_total++; + + if (endpoint != my_endpoint && !endpoint->GetConnected()) + continue; + + endpoints.push_back(endpoint); + } + + double startTime = Application::GetStartTime(); + + /* 30 seconds cold startup, don't update any authority to give the secondary endpoint time to reconnect. */ + if (num_total > 1 && endpoints.size() <= 1 && (startTime == 0 || Utility::GetTime() - startTime < 30)) + return; + + std::sort(endpoints.begin(), endpoints.end(), + [](const ConfigObject::Ptr& a, const ConfigObject::Ptr& b) { + return a->GetName() < b->GetName(); + } + ); + } + + for (const Type::Ptr& type : Type::GetAllTypes()) { + auto *dtype = dynamic_cast(type.get()); + + if (!dtype) + continue; + + for (const ConfigObject::Ptr& object : dtype->GetObjects()) { + if (!object->IsActive() || object->GetHAMode() != HARunOnce) + continue; + + bool authority; + + if (!my_zone) + authority = true; + else + authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint; + +#ifdef I2_DEBUG +// //Enable on demand, causes heavy logging on each run. +// Log(LogDebug, "ApiListener") +// << "Setting authority '" << Convert::ToString(authority) << "' for object '" << object->GetName() << "' of type '" << object->GetReflectionType()->GetName() << "'."; +#endif /* I2_DEBUG */ + + object->SetAuthority(authority); + } + } + + m_UpdatedObjectAuthority.store(true); +} -- cgit v1.2.3