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`.
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
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()));
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
}
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);
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);
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");
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) {
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);
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());
}
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)
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)
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;
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;
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();
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;
}
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);
}
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;
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());
}
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());
+ }
}
}
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());
};
[config, required] String author;
[config, required] String text;
+ [config] bool persistent;
[config] Timestamp expire_time;
[state] int legacy_id;
};
{
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]);
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]);
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)
{
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]);
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]);
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)
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)
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)