]> granicus.if.org Git - icinga2/blob - lib/icinga/checkable.cpp
Merge pull request #5929 from Icinga/feature/remove-boost-assign
[icinga2] / lib / icinga / checkable.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "icinga/checkable.hpp"
21 #include "icinga/checkable.tcpp"
22 #include "icinga/host.hpp"
23 #include "icinga/service.hpp"
24 #include "base/objectlock.hpp"
25 #include "base/utility.hpp"
26 #include "base/exception.hpp"
27
28 using namespace icinga;
29
30 REGISTER_TYPE_WITH_PROTOTYPE(Checkable, Checkable::GetPrototype());
31 INITIALIZE_ONCE(&Checkable::StaticInitialize);
32
33 boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, bool, bool, double, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementSet;
34 boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementCleared;
35
36 void Checkable::StaticInitialize(void)
37 {
38         /* fixed downtime start */
39         Downtime::OnDowntimeStarted.connect(std::bind(&Checkable::NotifyFixedDowntimeStart, _1));
40         /* flexible downtime start */
41         Downtime::OnDowntimeTriggered.connect(std::bind(&Checkable::NotifyFlexibleDowntimeStart, _1));
42         /* fixed/flexible downtime end */
43         Downtime::OnDowntimeRemoved.connect(std::bind(&Checkable::NotifyDowntimeEnd, _1));
44 }
45
46 Checkable::Checkable(void)
47         : m_CheckRunning(false)
48 {
49         SetSchedulingOffset(Utility::Random());
50 }
51
52 void Checkable::OnAllConfigLoaded(void)
53 {
54         ObjectImpl<Checkable>::OnAllConfigLoaded();
55
56         Endpoint::Ptr endpoint = GetCommandEndpoint();
57
58         if (endpoint) {
59                 Zone::Ptr checkableZone = static_pointer_cast<Zone>(GetZone());
60
61                 if (!checkableZone)
62                         checkableZone = Zone::GetLocalZone();
63
64                 Zone::Ptr cmdZone = endpoint->GetZone();
65
66                 if (checkableZone && cmdZone != checkableZone && cmdZone->GetParent() != checkableZone) {
67                         BOOST_THROW_EXCEPTION(ValidationError(this, { "command_endpoint" },
68                                 "Command endpoint must be in zone '" + checkableZone->GetName() + "' or in a direct child zone thereof."));
69                 }
70         }
71 }
72
73 void Checkable::Start(bool runtimeCreated)
74 {
75         double now = Utility::GetTime();
76
77         if (GetNextCheck() < now + 300)
78                 UpdateNextCheck();
79
80         ObjectImpl<Checkable>::Start(runtimeCreated);
81 }
82
83 void Checkable::AddGroup(const String& name)
84 {
85         boost::mutex::scoped_lock lock(m_CheckableMutex);
86
87         Array::Ptr groups;
88         Host *host = dynamic_cast<Host *>(this);
89
90         if (host)
91                 groups = host->GetGroups();
92         else
93                 groups = static_cast<Service *>(this)->GetGroups();
94
95         if (groups && groups->Contains(name))
96                 return;
97
98         if (!groups)
99                 groups = new Array();
100
101         groups->Add(name);
102 }
103
104 AcknowledgementType Checkable::GetAcknowledgement(void)
105 {
106         AcknowledgementType avalue = static_cast<AcknowledgementType>(GetAcknowledgementRaw());
107
108         if (avalue != AcknowledgementNone) {
109                 double expiry = GetAcknowledgementExpiry();
110
111                 if (expiry != 0 && expiry < Utility::GetTime()) {
112                         avalue = AcknowledgementNone;
113                         ClearAcknowledgement();
114                 }
115         }
116
117         return avalue;
118 }
119
120 bool Checkable::IsAcknowledged(void) const
121 {
122         return const_cast<Checkable *>(this)->GetAcknowledgement() != AcknowledgementNone;
123 }
124
125 void Checkable::AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify, bool persistent, double expiry, const MessageOrigin::Ptr& origin)
126 {
127         SetAcknowledgementRaw(type);
128         SetAcknowledgementExpiry(expiry);
129
130         if (notify && !IsPaused())
131                 OnNotificationsRequested(this, NotificationAcknowledgement, GetLastCheckResult(), author, comment, nullptr);
132
133         OnAcknowledgementSet(this, author, comment, type, notify, persistent, expiry, origin);
134 }
135
136 void Checkable::ClearAcknowledgement(const MessageOrigin::Ptr& origin)
137 {
138         SetAcknowledgementRaw(AcknowledgementNone);
139         SetAcknowledgementExpiry(0);
140
141         OnAcknowledgementCleared(this, origin);
142 }
143
144 Endpoint::Ptr Checkable::GetCommandEndpoint(void) const
145 {
146         return Endpoint::GetByName(GetCommandEndpointRaw());
147 }
148
149 int Checkable::GetSeverity(void) const
150 {
151         /* overridden in Host/Service class. */
152         return 0;
153 }
154
155 void Checkable::NotifyFixedDowntimeStart(const Downtime::Ptr& downtime)
156 {
157         if (!downtime->GetFixed())
158                 return;
159
160         NotifyDowntimeInternal(downtime);
161 }
162
163 void Checkable::NotifyFlexibleDowntimeStart(const Downtime::Ptr& downtime)
164 {
165         if (downtime->GetFixed())
166                 return;
167
168         NotifyDowntimeInternal(downtime);
169 }
170
171 void Checkable::NotifyDowntimeInternal(const Downtime::Ptr& downtime)
172 {
173         Checkable::Ptr checkable = downtime->GetCheckable();
174
175         if (!checkable->IsPaused())
176                 OnNotificationsRequested(checkable, NotificationDowntimeStart, checkable->GetLastCheckResult(), downtime->GetAuthor(), downtime->GetComment(), nullptr);
177 }
178
179 void Checkable::NotifyDowntimeEnd(const Downtime::Ptr& downtime)
180 {
181         /* don't send notifications for flexible downtimes which never triggered */
182         if (!downtime->GetFixed() && !downtime->IsTriggered())
183                 return;
184
185         Checkable::Ptr checkable = downtime->GetCheckable();
186
187         if (!checkable->IsPaused())
188                 OnNotificationsRequested(checkable, NotificationDowntimeEnd, checkable->GetLastCheckResult(), downtime->GetAuthor(), downtime->GetComment(), nullptr);
189 }
190
191 void Checkable::ValidateCheckInterval(double value, const ValidationUtils& utils)
192 {
193         ObjectImpl<Checkable>::ValidateCheckInterval(value, utils);
194
195         if (value <= 0)
196                 BOOST_THROW_EXCEPTION(ValidationError(this, { "check_interval" }, "Interval must be greater than 0."));
197 }
198
199 void Checkable::ValidateMaxCheckAttempts(int value, const ValidationUtils& utils)
200 {
201         ObjectImpl<Checkable>::ValidateMaxCheckAttempts(value, utils);
202
203         if (value <= 0)
204                 BOOST_THROW_EXCEPTION(ValidationError(this, { "max_check_attempts" }, "Value must be greater than 0."));
205 }