1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ 2 3 #include "remote/zone.hpp" 4 #include "remote/apilistener.hpp" 5 #include "base/configtype.hpp" 6 #include "base/utility.hpp" 7 #include "base/convert.hpp" 8 9 using namespace icinga; 10 11 std::atomic<bool> ApiListener::m_UpdatedObjectAuthority (false); 12 UpdateObjectAuthority()13void ApiListener::UpdateObjectAuthority() 14 { 15 /* Always run this, even if there is no 'api' feature enabled. */ 16 if (auto listener = ApiListener::GetInstance()) { 17 Log(LogNotice, "ApiListener") 18 << "Updating object authority for objects at endpoint '" << listener->GetIdentity() << "'."; 19 } else { 20 Log(LogNotice, "ApiListener") 21 << "Updating object authority for local objects."; 22 } 23 24 Zone::Ptr my_zone = Zone::GetLocalZone(); 25 26 std::vector<Endpoint::Ptr> endpoints; 27 Endpoint::Ptr my_endpoint; 28 29 if (my_zone) { 30 my_endpoint = Endpoint::GetLocalEndpoint(); 31 32 int num_total = 0; 33 34 for (const Endpoint::Ptr& endpoint : my_zone->GetEndpoints()) { 35 num_total++; 36 37 if (endpoint != my_endpoint && !endpoint->GetConnected()) 38 continue; 39 40 endpoints.push_back(endpoint); 41 } 42 43 double startTime = Application::GetStartTime(); 44 45 /* 30 seconds cold startup, don't update any authority to give the secondary endpoint time to reconnect. */ 46 if (num_total > 1 && endpoints.size() <= 1 && (startTime == 0 || Utility::GetTime() - startTime < 30)) 47 return; 48 49 std::sort(endpoints.begin(), endpoints.end(), 50 [](const ConfigObject::Ptr& a, const ConfigObject::Ptr& b) { 51 return a->GetName() < b->GetName(); 52 } 53 ); 54 } 55 56 for (const Type::Ptr& type : Type::GetAllTypes()) { 57 auto *dtype = dynamic_cast<ConfigType *>(type.get()); 58 59 if (!dtype) 60 continue; 61 62 for (const ConfigObject::Ptr& object : dtype->GetObjects()) { 63 if (!object->IsActive() || object->GetHAMode() != HARunOnce) 64 continue; 65 66 bool authority; 67 68 if (!my_zone) 69 authority = true; 70 else 71 authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint; 72 73 #ifdef I2_DEBUG 74 // //Enable on demand, causes heavy logging on each run. 75 // Log(LogDebug, "ApiListener") 76 // << "Setting authority '" << Convert::ToString(authority) << "' for object '" << object->GetName() << "' of type '" << object->GetReflectionType()->GetName() << "'."; 77 #endif /* I2_DEBUG */ 78 79 object->SetAuthority(authority); 80 } 81 } 82 83 m_UpdatedObjectAuthority.store(true); 84 } 85