Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix persistent comments for Acknowledgements #4956

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions doc/12-icinga2-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -905,13 +905,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`.
persistent | 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
1 change: 1 addition & 0 deletions doc/9-object-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ Configuration Attributes:
entry_time | **Optional.** The unix timestamp when this comment was added.
entry_type | **Optional.** The comment type (`User` = 1, `Downtime` = 2, `Flapping` = 3, `Acknowledgement` = 4).
expire_time | **Optional.** The comment's expire time as unix timestamp.
persistent | **Optional.** Only evaluated for `entry_type` Acknowledgement. `true` does not remove the comment when the acknowledgement is removed.

## <a id="objecttype-compatlogger"></a> CompatLogger

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->GetPersistent() ? 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 persistent = 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("persistent"))
persistent = HttpUtility::GetLastParameter(params, "persistent");
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"), persistent, 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 persistent, 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("persistent", persistent);
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 persistent, 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 persistent comments from an acknowledgement */
if (comment->GetEntryType() == CommentAcknowledgement && comment->GetPersistent())
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) const
return const_cast<Checkable *>(this)->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 persistent, 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, persistent, 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 @@ -98,7 +98,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 persistent = false, double expiry = 0, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
void ClearAcknowledgement(const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());

virtual int GetSeverity(void) const override;
Expand Down Expand Up @@ -139,7 +139,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 persistent, 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("persistent"), 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 persistent, 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
12 changes: 9 additions & 3 deletions 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 persistent, 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("persistent", persistent);
attrs->Set("expire_time", expireTime);
attrs->Set("entry_type", entryType);
attrs->Set("entry_time", Utility::GetTime());
Expand Down Expand Up @@ -247,8 +248,13 @@ void Comment::CommentsExpireTimerHandler(void)
}

for (const Comment::Ptr& comment : comments) {
/* Only remove comment which are activated after daemon start. */
if (comment->IsActive() && comment->IsExpired())
/* Only remove comments which are activated after daemon start. */
if (comment->IsActive() && comment->IsExpired()) {
/* Do not remove persistent comments from an acknowledgement */
if (comment->GetEntryType() == CommentAcknowledgement && comment->GetPersistent())
continue;

RemoveComment(comment->GetName());
}
}
}
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 persistent, 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 persistent;
[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 persistent = (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], persistent, 0);
service->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, persistent, 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 persistent = (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], persistent, timestamp);
service->AcknowledgeProblem(arguments[6], arguments[7], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, persistent, 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 persistent = (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], persistent, 0);
host->AcknowledgeProblem(arguments[4], arguments[5], sticky ? AcknowledgementSticky : AcknowledgementNormal, persistent, 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 persistent = (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], persistent, timestamp);
host->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, persistent, 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