Skip to content

Commit

Permalink
Fix persistent comments for Acknowledgements
Browse files Browse the repository at this point in the history
refs #4818
  • Loading branch information
TheFlyingCorpse committed Mar 1, 2017
1 parent bb2ee7f commit 1604657
Show file tree
Hide file tree
Showing 14 changed files with 51 additions and 32 deletions.
15 changes: 8 additions & 7 deletions doc/12-icinga2-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -901,13 +901,14 @@ are disabled.

Send a `POST` request to the URL endpoint `/v1/actions/acknowledge-problem`.

Parameter | Type | Description
----------|-----------|--------------
author | string | **Required.** Name of the author, may be empty.
comment | string | **Required.** Comment text, may be empty.
expiry | timestamp | **Optional.** Whether the acknowledgement will be removed at the timestamp.
sticky | boolean | **Optional.** Whether the acknowledgement will be set until the service or host fully recovers. Defaults to `false`.
notify | boolean | **Optional.** Whether a notification of the `Acknowledgement` type will be sent. Defaults to `false`.
Parameter | Type | Description
---------------------|-----------|--------------
author | string | **Required.** Name of the author, may be empty.
comment | string | **Required.** Comment text, may be empty.
expiry | timestamp | **Optional.** Whether the acknowledgement will be removed at the timestamp.
sticky | boolean | **Optional.** Whether the acknowledgement will be set until the service or host fully recovers. Defaults to `false`.
notify | boolean | **Optional.** Whether a notification of the `Acknowledgement` type will be sent. Defaults to `false`.
comment\_persistance | boolean | **Optional.** When the comment is of type `Acknowledgement` and this is set to `true`, the comment will remain after the acknowledgement recovers or expires. Defaults to `false`.

In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.

Expand Down
2 changes: 1 addition & 1 deletion lib/db_ido/dbevents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ void DbEvents::AddCommentInternal(std::vector<DbQuery>& queries, const Comment::
fields1->Set("comment_time", DbValue::FromTimestamp(entry_time)); /* same as entry_time */
fields1->Set("author_name", comment->GetAuthor());
fields1->Set("comment_data", comment->GetText());
fields1->Set("is_persistent", 1);
fields1->Set("is_persistent", (comment->GetCommentPersistance() == true) ? 1 : 0);
fields1->Set("comment_source", 1); /* external */
fields1->Set("expires", (comment->GetExpireTime() > 0) ? 1 : 0);
fields1->Set("expiration_time", DbValue::FromTimestamp(comment->GetExpireTime()));
Expand Down
7 changes: 5 additions & 2 deletions lib/icinga/apiactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,15 @@ Dictionary::Ptr ApiActions::AcknowledgeProblem(const ConfigObject::Ptr& object,

AcknowledgementType sticky = AcknowledgementNormal;
bool notify = false;
bool comment_persistance = false;
double timestamp = 0.0;

if (params->Contains("sticky") && HttpUtility::GetLastParameter(params, "sticky"))
sticky = AcknowledgementSticky;
if (params->Contains("notify"))
notify = HttpUtility::GetLastParameter(params, "notify");
if (params->Contains("comment_persistance"))
comment_persistance = HttpUtility::GetLastParameter(params, "comment_persistance");
if (params->Contains("expiry"))
timestamp = HttpUtility::GetLastParameter(params, "expiry");
else
Expand All @@ -218,7 +221,7 @@ Dictionary::Ptr ApiActions::AcknowledgeProblem(const ConfigObject::Ptr& object,
}

Comment::AddComment(checkable, CommentAcknowledgement, HttpUtility::GetLastParameter(params, "author"),
HttpUtility::GetLastParameter(params, "comment"), timestamp);
HttpUtility::GetLastParameter(params, "comment"), comment_persistance, timestamp);
checkable->AcknowledgeProblem(HttpUtility::GetLastParameter(params, "author"),
HttpUtility::GetLastParameter(params, "comment"), sticky, notify, timestamp);

Expand Down Expand Up @@ -254,7 +257,7 @@ Dictionary::Ptr ApiActions::AddComment(const ConfigObject::Ptr& object,

String commentName = Comment::AddComment(checkable, CommentUser,
HttpUtility::GetLastParameter(params, "author"),
HttpUtility::GetLastParameter(params, "comment"), 0);
HttpUtility::GetLastParameter(params, "comment"), false, 0);

Comment::Ptr comment = Comment::GetByName(commentName);

Expand Down
3 changes: 2 additions & 1 deletion lib/icinga/apievents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ void ApiEvents::FlappingChangedHandler(const Checkable::Ptr& checkable, const Me

void ApiEvents::AcknowledgementSetHandler(const Checkable::Ptr& checkable,
const String& author, const String& comment, AcknowledgementType type,
bool notify, double expiry, const MessageOrigin::Ptr& origin)
bool notify, bool comment_persistance, double expiry, const MessageOrigin::Ptr& origin)
{
std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("AcknowledgementSet");

Expand Down Expand Up @@ -206,6 +206,7 @@ void ApiEvents::AcknowledgementSetHandler(const Checkable::Ptr& checkable,
result->Set("comment", comment);
result->Set("acknowledgement_type", type);
result->Set("notify", notify);
result->Set("comment_persistance", comment_persistance);
result->Set("expiry", expiry);

for (const EventQueue::Ptr& queue : queues) {
Expand Down
2 changes: 1 addition & 1 deletion lib/icinga/apievents.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class I2_ICINGA_API ApiEvents

static void AcknowledgementSetHandler(const Checkable::Ptr& checkable,
const String& author, const String& comment, AcknowledgementType type,
bool notify, double expiry, const MessageOrigin::Ptr& origin);
bool notify, bool comment_persistance, double expiry, const MessageOrigin::Ptr& origin);
static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin);

static void CommentAddedHandler(const Comment::Ptr& comment);
Expand Down
4 changes: 4 additions & 0 deletions lib/icinga/checkable-comment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ void Checkable::RemoveAllComments(void)
void Checkable::RemoveCommentsByType(int type)
{
for (const Comment::Ptr& comment : GetComments()) {
/* Do not remove comments set as true in comment_persistance when it originates from an Acknowledgement */
if (comment->GetEntryType() == CommentAcknowledgement && comment->GetCommentPersistance())
continue;

if (comment->GetEntryType() == type)
Comment::RemoveComment(comment->GetName());
}
Expand Down
6 changes: 3 additions & 3 deletions lib/icinga/checkable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ using namespace icinga;
REGISTER_TYPE_WITH_PROTOTYPE(Checkable, Checkable::GetPrototype());
INITIALIZE_ONCE(&Checkable::StaticInitialize);

boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, bool, double, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementSet;
boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, bool, bool, double, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementSet;
boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementCleared;

void Checkable::StaticInitialize(void)
Expand Down Expand Up @@ -122,15 +122,15 @@ bool Checkable::IsAcknowledged(void)
return GetAcknowledgement() != AcknowledgementNone;
}

void Checkable::AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify, double expiry, const MessageOrigin::Ptr& origin)
void Checkable::AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify, bool comment_persistance, double expiry, const MessageOrigin::Ptr& origin)
{
SetAcknowledgementRaw(type);
SetAcknowledgementExpiry(expiry);

if (notify && !IsPaused())
OnNotificationsRequested(this, NotificationAcknowledgement, GetLastCheckResult(), author, comment, MessageOrigin::Ptr());

OnAcknowledgementSet(this, author, comment, type, notify, expiry, origin);
OnAcknowledgementSet(this, author, comment, type, notify, comment_persistance, expiry, origin);
}

void Checkable::ClearAcknowledgement(const MessageOrigin::Ptr& origin)
Expand Down
4 changes: 2 additions & 2 deletions lib/icinga/checkable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class I2_ICINGA_API Checkable : public ObjectImpl<Checkable>

AcknowledgementType GetAcknowledgement(void);

void AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify = true, double expiry = 0, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
void AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify = true, bool comment_persistance = false, double expiry = 0, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
void ClearAcknowledgement(const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());

/* Checks */
Expand Down Expand Up @@ -121,7 +121,7 @@ class I2_ICINGA_API Checkable : public ObjectImpl<Checkable>
const NotificationType&, const CheckResult::Ptr&, const String&,
const String&, const MessageOrigin::Ptr&)> OnNotificationSentToAllUsers;
static boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType,
bool, double, const MessageOrigin::Ptr&)> OnAcknowledgementSet;
bool, bool, double, const MessageOrigin::Ptr&)> OnAcknowledgementSet;
static boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin::Ptr&)> OnAcknowledgementCleared;
static boost::signals2::signal<void (const Checkable::Ptr&)> OnNextCheckUpdated;
static boost::signals2::signal<void (const Checkable::Ptr&)> OnEventCommandExecuted;
Expand Down
4 changes: 2 additions & 2 deletions lib/icinga/clusterevents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ Value ClusterEvents::ForceNextNotificationChangedAPIHandler(const MessageOrigin:

void ClusterEvents::AcknowledgementSetHandler(const Checkable::Ptr& checkable,
const String& author, const String& comment, AcknowledgementType type,
bool notify, double expiry, const MessageOrigin::Ptr& origin)
bool notify, bool comment_persistance, double expiry, const MessageOrigin::Ptr& origin)
{
ApiListener::Ptr listener = ApiListener::GetInstance();

Expand Down Expand Up @@ -510,7 +510,7 @@ Value ClusterEvents::AcknowledgementSetAPIHandler(const MessageOrigin::Ptr& orig

checkable->AcknowledgeProblem(params->Get("author"), params->Get("comment"),
static_cast<AcknowledgementType>(static_cast<int>(params->Get("acktype"))),
params->Get("notify"), params->Get("expiry"), origin);
params->Get("notify"), params->Get("comment_persistance"), params->Get("expiry"), origin);

return Empty;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/icinga/clusterevents.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class I2_ICINGA_API ClusterEvents
static Value ForceNextNotificationChangedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);

static void AcknowledgementSetHandler(const Checkable::Ptr& checkable, const String& author, const String& comment, AcknowledgementType type,
bool notify, double expiry, const MessageOrigin::Ptr& origin);
bool notify, bool comment_persistance, double expiry, const MessageOrigin::Ptr& origin);
static Value AcknowledgementSetAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);

static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin);
Expand Down
7 changes: 6 additions & 1 deletion lib/icinga/comment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ int Comment::GetNextCommentID(void)
}

String Comment::AddComment(const Checkable::Ptr& checkable, CommentType entryType, const String& author,
const String& text, double expireTime, const String& id, const MessageOrigin::Ptr& origin)
const String& text, bool comment_persistance, double expireTime, const String& id, const MessageOrigin::Ptr& origin)
{
String fullName;

Expand All @@ -163,6 +163,7 @@ String Comment::AddComment(const Checkable::Ptr& checkable, CommentType entryTyp

attrs->Set("author", author);
attrs->Set("text", text);
attrs->Set("comment_persistance", comment_persistance);
attrs->Set("expire_time", expireTime);
attrs->Set("entry_type", entryType);
attrs->Set("entry_time", Utility::GetTime());
Expand Down Expand Up @@ -247,6 +248,10 @@ void Comment::CommentsExpireTimerHandler(void)
}

for (const Comment::Ptr& comment : comments) {
/* Do not remove comments set as persistent when it originates from an Acknowledgement */
if (comment->GetEntryType() == CommentAcknowledgement && comment->IsActive() && comment->IsExpired() && comment->GetCommentPersistance())
continue;

/* Only remove comment which are activated after daemon start. */
if (comment->IsActive() && comment->IsExpired())
RemoveComment(comment->GetName());
Expand Down
2 changes: 1 addition & 1 deletion lib/icinga/comment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class I2_ICINGA_API Comment : public ObjectImpl<Comment>
static int GetNextCommentID(void);

static String AddComment(const intrusive_ptr<Checkable>& checkable, CommentType entryType,
const String& author, const String& text, double expireTime,
const String& author, const String& text, bool comment_persistance, double expireTime,
const String& id = String(), const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());

static void RemoveComment(const String& id, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
Expand Down
1 change: 1 addition & 0 deletions lib/icinga/comment.ti
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class Comment : ConfigObject < CommentNameComposer
};
[config, required] String author;
[config, required] String text;
[config] bool comment_persistance;
[config] Timestamp expire_time;
[state] int legacy_id;
};
Expand Down
24 changes: 14 additions & 10 deletions lib/icinga/externalcommandprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const std::vector<S
{
bool sticky = (Convert::ToLong(arguments[2]) == 2 ? true : false);
bool notify = (Convert::ToLong(arguments[3]) > 0 ? true : false);
bool comment_persistance = (Convert::ToLong(arguments[4]) > 0 ? true : false);

Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);

Expand All @@ -633,14 +634,15 @@ void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const std::vector<S
Log(LogNotice, "ExternalCommandProcessor")
<< "Setting acknowledgement for service '" << service->GetName() << "'" << (notify ? "" : ". Disabled notification");

Comment::AddComment(service, CommentAcknowledgement, arguments[5], arguments[6], 0);
service->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify);
Comment::AddComment(service, CommentAcknowledgement, arguments[5], arguments[6], comment_persistance, 0);
service->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, comment_persistance, notify);
}

void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const std::vector<String>& arguments)
{
bool sticky = (Convert::ToLong(arguments[2]) == 2 ? true : false);
bool notify = (Convert::ToLong(arguments[3]) > 0 ? true : false);
bool comment_persistance = (Convert::ToLong(arguments[4]) > 0 ? true : false);
double timestamp = Convert::ToDouble(arguments[5]);

Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Expand All @@ -654,8 +656,8 @@ void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const std::ve
Log(LogNotice, "ExternalCommandProcessor")
<< "Setting timed acknowledgement for service '" << service->GetName() << "'" << (notify ? "" : ". Disabled notification");

Comment::AddComment(service, CommentAcknowledgement, arguments[6], arguments[7], timestamp);
service->AcknowledgeProblem(arguments[6], arguments[7], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, timestamp);
Comment::AddComment(service, CommentAcknowledgement, arguments[6], arguments[7], comment_persistance, timestamp);
service->AcknowledgeProblem(arguments[6], arguments[7], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, comment_persistance, timestamp);
}

void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const std::vector<String>& arguments)
Expand All @@ -680,6 +682,7 @@ void ExternalCommandProcessor::AcknowledgeHostProblem(double, const std::vector<
{
bool sticky = (Convert::ToLong(arguments[1]) == 2 ? true : false);
bool notify = (Convert::ToLong(arguments[2]) > 0 ? true : false);
bool comment_persistance = (Convert::ToLong(arguments[3]) > 0 ? true : false);

Host::Ptr host = Host::GetByName(arguments[0]);

Expand All @@ -692,14 +695,15 @@ void ExternalCommandProcessor::AcknowledgeHostProblem(double, const std::vector<
if (host->GetState() == HostUp)
BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));

Comment::AddComment(host, CommentAcknowledgement, arguments[4], arguments[5], 0);
host->AcknowledgeProblem(arguments[4], arguments[5], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify);
Comment::AddComment(host, CommentAcknowledgement, arguments[4], arguments[5], comment_persistance, 0);
host->AcknowledgeProblem(arguments[4], arguments[5], sticky ? AcknowledgementSticky : AcknowledgementNormal, comment_persistance, notify);
}

void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const std::vector<String>& arguments)
{
bool sticky = (Convert::ToLong(arguments[1]) == 2 ? true : false);
bool notify = (Convert::ToLong(arguments[2]) > 0 ? true : false);
bool comment_persistance = (Convert::ToLong(arguments[3]) > 0 ? true : false);
double timestamp = Convert::ToDouble(arguments[4]);

Host::Ptr host = Host::GetByName(arguments[0]);
Expand All @@ -713,8 +717,8 @@ void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const std::v
if (host->GetState() == HostUp)
BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));

Comment::AddComment(host, CommentAcknowledgement, arguments[5], arguments[6], timestamp);
host->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, timestamp);
Comment::AddComment(host, CommentAcknowledgement, arguments[5], arguments[6], comment_persistance, timestamp);
host->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, comment_persistance, timestamp);
}

void ExternalCommandProcessor::RemoveHostAcknowledgement(double, const std::vector<String>& arguments)
Expand Down Expand Up @@ -1286,7 +1290,7 @@ void ExternalCommandProcessor::AddHostComment(double, const std::vector<String>&

Log(LogNotice, "ExternalCommandProcessor")
<< "Creating comment for host " << host->GetName();
(void) Comment::AddComment(host, CommentUser, arguments[2], arguments[3], 0);
(void) Comment::AddComment(host, CommentUser, arguments[2], arguments[3], false, 0);
}

void ExternalCommandProcessor::DelHostComment(double, const std::vector<String>& arguments)
Expand All @@ -1310,7 +1314,7 @@ void ExternalCommandProcessor::AddSvcComment(double, const std::vector<String>&

Log(LogNotice, "ExternalCommandProcessor")
<< "Creating comment for service " << service->GetName();
(void) Comment::AddComment(service, CommentUser, arguments[3], arguments[4], 0);
(void) Comment::AddComment(service, CommentUser, arguments[3], arguments[4], false, 0);
}

void ExternalCommandProcessor::DelSvcComment(double, const std::vector<String>& arguments)
Expand Down

0 comments on commit 1604657

Please sign in to comment.