1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ 2 3 #include "remote/zone.hpp" 4 #include "remote/zone-ti.cpp" 5 #include "remote/jsonrpcconnection.hpp" 6 #include "base/array.hpp" 7 #include "base/objectlock.hpp" 8 #include "base/logger.hpp" 9 10 using namespace icinga; 11 12 REGISTER_TYPE(Zone); 13 OnAllConfigLoaded()14void Zone::OnAllConfigLoaded() 15 { 16 ObjectImpl<Zone>::OnAllConfigLoaded(); 17 18 m_Parent = Zone::GetByName(GetParentRaw()); 19 20 if (m_Parent && m_Parent->IsGlobal()) 21 BOOST_THROW_EXCEPTION(ScriptError("Zone '" + GetName() + "' can not have a global zone as parent.", GetDebugInfo())); 22 23 Zone::Ptr zone = m_Parent; 24 int levels = 0; 25 26 Array::Ptr endpoints = GetEndpointsRaw(); 27 28 if (endpoints) { 29 ObjectLock olock(endpoints); 30 for (const String& endpoint : endpoints) { 31 Endpoint::Ptr ep = Endpoint::GetByName(endpoint); 32 33 if (ep) 34 ep->SetCachedZone(this); 35 } 36 } 37 38 while (zone) { 39 m_AllParents.push_back(zone); 40 41 zone = Zone::GetByName(zone->GetParentRaw()); 42 levels++; 43 44 if (levels > 32) 45 BOOST_THROW_EXCEPTION(ScriptError("Infinite recursion detected while resolving zone graph. Check your zone hierarchy.", GetDebugInfo())); 46 } 47 } 48 GetParent() const49Zone::Ptr Zone::GetParent() const 50 { 51 return m_Parent; 52 } 53 GetEndpoints() const54std::set<Endpoint::Ptr> Zone::GetEndpoints() const 55 { 56 std::set<Endpoint::Ptr> result; 57 58 Array::Ptr endpoints = GetEndpointsRaw(); 59 60 if (endpoints) { 61 ObjectLock olock(endpoints); 62 63 for (const String& name : endpoints) { 64 Endpoint::Ptr endpoint = Endpoint::GetByName(name); 65 66 if (!endpoint) 67 continue; 68 69 result.insert(endpoint); 70 } 71 } 72 73 return result; 74 } 75 GetAllParentsRaw() const76std::vector<Zone::Ptr> Zone::GetAllParentsRaw() const 77 { 78 return m_AllParents; 79 } 80 GetAllParents() const81Array::Ptr Zone::GetAllParents() const 82 { 83 auto result (new Array); 84 85 for (auto& parent : m_AllParents) 86 result->Add(parent->GetName()); 87 88 return result; 89 } 90 CanAccessObject(const ConfigObject::Ptr & object)91bool Zone::CanAccessObject(const ConfigObject::Ptr& object) 92 { 93 Zone::Ptr object_zone; 94 95 if (object->GetReflectionType() == Zone::TypeInstance) 96 object_zone = static_pointer_cast<Zone>(object); 97 else 98 object_zone = static_pointer_cast<Zone>(object->GetZone()); 99 100 if (!object_zone) 101 object_zone = Zone::GetLocalZone(); 102 103 if (object_zone->GetGlobal()) 104 return true; 105 106 return object_zone->IsChildOf(this); 107 } 108 IsChildOf(const Zone::Ptr & zone)109bool Zone::IsChildOf(const Zone::Ptr& zone) 110 { 111 Zone::Ptr azone = this; 112 113 while (azone) { 114 if (azone == zone) 115 return true; 116 117 azone = azone->GetParent(); 118 } 119 120 return false; 121 } 122 IsGlobal() const123bool Zone::IsGlobal() const 124 { 125 return GetGlobal(); 126 } 127 IsSingleInstance() const128bool Zone::IsSingleInstance() const 129 { 130 Array::Ptr endpoints = GetEndpointsRaw(); 131 return !endpoints || endpoints->GetLength() < 2; 132 } 133 GetLocalZone()134Zone::Ptr Zone::GetLocalZone() 135 { 136 Endpoint::Ptr local = Endpoint::GetLocalEndpoint(); 137 138 if (!local) 139 return nullptr; 140 141 return local->GetZone(); 142 } 143 ValidateEndpointsRaw(const Lazy<Array::Ptr> & lvalue,const ValidationUtils & utils)144void Zone::ValidateEndpointsRaw(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) 145 { 146 ObjectImpl<Zone>::ValidateEndpointsRaw(lvalue, utils); 147 148 if (lvalue() && lvalue()->GetLength() > 2) { 149 Log(LogWarning, "Zone") 150 << "The Zone object '" << GetName() << "' has more than two endpoints." 151 << " Due to a known issue this type of configuration is strongly" 152 << " discouraged and may cause Icinga to use excessive amounts of CPU time."; 153 } 154 } 155