From 1d2606cbfeb2fa70ba63dfedee0df86a0c49c1c9 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Sun, 8 Nov 2015 12:41:47 +0100 Subject: [PATCH] Add filter targets for remove-{comment,downtime} actions Drop remove-all-{comments,downtimes}. This is provided by using host and service filters. fixes #10561 --- doc/9-icinga2-api.md | 107 ++++++++++++++---------------------- lib/icinga/apiactions.cpp | 110 +++++++++++++++++++------------------- lib/icinga/apiactions.hpp | 2 - 3 files changed, 93 insertions(+), 126 deletions(-) diff --git a/doc/9-icinga2-api.md b/doc/9-icinga2-api.md index 90beb98e6..650bd9b76 100644 --- a/doc/9-icinga2-api.md +++ b/doc/9-icinga2-api.md @@ -257,13 +257,13 @@ If you're only interested in a single object you can limit the output to that ob https://localhost:5665/v1/objects/hosts?host=localhost -The name of the URL parameter is the lower-case version of the type the query applies to. For +**The name of the URL parameter is the lower-case version of the type the query applies to.** For example, for `Host` objects the URL parameter therefore is `host`, for `Service` objects it is `service` and so on. You can also specify multiple objects: - https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host + https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host Again - like in the previous example - the name of the URL parameter is the lower-case version of the type. However, because we're specifying multiple objects here the **plural form** of the type is used. @@ -578,30 +578,6 @@ The following example adds a comment for all `ping4` services: ] } -### remove-all-comments - -Removes all comments for services or hosts. - -Send a `POST` request to the URL endpoint `/v1/actions/remove-all-comments`. - -A [filter](9-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. - -The following example removes all comments from all services: - - $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-all-comments?type=Service' | python -m json.tool - - { - "results": [ - { - "code": 200.0, - "status": "Successfully removed comments for object 'example2.localdomain!aws-health'." - }, - { - "code": 200.0, - "status": "Successfully removed comments for object 'example.localdomain!aws-health'." - } - } - ### remove-comment Remove the comment using its `name` attribute , returns `OK` if the @@ -611,24 +587,37 @@ Icinga 2 when [adding a comment](9-icinga2-api.md#icinga2-api-actions-add-commen Send a `POST` request to the URL endpoint `/v1/actions/remove-comment`. - Parameter | Type | Description - ------------|---------|-------------- - name | string | **Required.** Name of the comment to remove. +A [filter](9-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Comment`. -Does not support a target type or filters. +Example for a simple filter using the `comment` URL parameter: -Example: - - $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-comment?name=example.localdomain!ping4!example.localdomain-1446824161-0' | python -m json.tool + $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-comment?comment=example2.localdomain!ping4!mbmif.local-1446986367-0' | python -m json.tool { "results": [ { "code": 200.0, - "status": "Successfully removed comment 'example.localdomain!ping4!example.localdomain-1446824161-0'." + "status": "Successfully removed comment 'example2.localdomain!ping4!mbmif.local-1446986367-0'." } ] } +Example for removing all service comments using a service name filter for `ping4`: + + $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-comment?filter=service.name==%22ping4%22&type=Service' | python -m json.tool + { + "results": [ + { + "code": 200.0, + "status": "Successfully removed all comments for object 'example2.localdomain!ping4'." + }, + { + "code": 200.0, + "status": "Successfully removed all comments for object 'example.localdomain!ping4'." + } + ] + } + + ### schedule-downtime Schedule a downtime for hosts and services. @@ -665,32 +654,6 @@ Example: ] } - -### remove-all-downtimes - -Removes all downtimes for services or hosts. - -Send a `POST` request to the URL endpoint `/v1/actions/remove-all-downtimes`. - -A [filter](9-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. - -The following example removes all downtimes for all `ping4` services: - - $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-all-downtimes?type=Service&filter=service.name==%22ping4%22' | python -m json.tool - - { - "results": [ - { - "code": 200.0, - "status": "Successfully removed downtimes for object 'example2.localdomain!ping4'." - }, - { - "code": 200.0, - "status": "Successfully removed downtimes for object 'example.localdomain!ping4'." - } - ] - } - ### remove-downtime Remove the downtime using its `name` attribute , returns `OK` if the @@ -700,20 +663,28 @@ Icinga 2 when [scheduling a downtime](9-icinga2-api.md#icinga2-api-actions-sched Send a `POST` request to the URL endpoint `/v1/actions/remove-downtime`. - Parameter | Type | Description - -------------|---------|-------------- - name | string | **Required.** Name of the downtime to remove. +A [filter](9-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Downtime`. -Does not support a target type or filter. +Example for a simple filter using the `downtime` URL parameter: -Example: - - $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime?name=example.localdomain!ping4!example.localdomain-1446822004-1' | python -m json.tool + $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime?downtime=example.localdomain!ping4!mbmif.local-1446979168-6' | python -m json.tool { "results": [ { "code": 200.0, - "status": "Successfully removed downtime 'example.localdomain!ping4!example.localdomain-1446822004-1'." + "status": "Successfully removed downtime 'example.localdomain!ping4!mbmif.local-1446979168-6'." + } + ] + } + +Example for removing all host downtimes using a host name filter for `example.localdomain`: + + $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime?filter=host.name==%22example.localdomain%22&type=Host' | python -m json.tool + { + "results": [ + { + "code": 200.0, + "status": "Successfully removed all downtimes for object 'example.localdomain'." } ] } diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index d73040402..9ce515edd 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -40,11 +40,9 @@ REGISTER_APIACTION(delay_notification, "Service;Host", &ApiActions::DelayNotific REGISTER_APIACTION(acknowledge_problem, "Service;Host", &ApiActions::AcknowledgeProblem); REGISTER_APIACTION(remove_acknowledgement, "Service;Host", &ApiActions::RemoveAcknowledgement); REGISTER_APIACTION(add_comment, "Service;Host", &ApiActions::AddComment); -REGISTER_APIACTION(remove_all_comments, "Service;Host", &ApiActions::RemoveAllComments); -REGISTER_APIACTION(remove_comment, "", &ApiActions::RemoveComment); +REGISTER_APIACTION(remove_comment, "Service;Host;Comment", &ApiActions::RemoveComment); REGISTER_APIACTION(schedule_downtime, "Service;Host", &ApiActions::ScheduleDowntime); -REGISTER_APIACTION(remove_all_downtimes, "Service;Host", &ApiActions::RemoveAllDowntimes); -REGISTER_APIACTION(remove_downtime, "", &ApiActions::RemoveDowntime); +REGISTER_APIACTION(remove_downtime, "Service;Host;Downtime", &ApiActions::RemoveDowntime); REGISTER_APIACTION(shutdown_process, "", &ApiActions::ShutdownProcess); REGISTER_APIACTION(restart_process, "", &ApiActions::RestartProcess); @@ -250,51 +248,51 @@ Dictionary::Ptr ApiActions::AddComment(const ConfigObject::Ptr& object, if (!params->Contains("author") || !params->Contains("comment")) return ApiActions::CreateResult(403, "Comments require author and comment."); - String comment_name = Comment::AddComment(checkable, CommentUser, + String commentName = Comment::AddComment(checkable, CommentUser, HttpUtility::GetLastParameter(params, "author"), HttpUtility::GetLastParameter(params, "comment"), 0); - Comment::Ptr comment = Comment::GetByName(comment_name); - int legacy_id = comment->GetLegacyId(); + Comment::Ptr comment = Comment::GetByName(commentName); Dictionary::Ptr additional = new Dictionary(); - additional->Set("name", comment_name); - additional->Set("legacy_id", legacy_id); + additional->Set("name", commentName); + additional->Set("legacy_id", comment->GetLegacyId()); return ApiActions::CreateResult(200, "Successfully added comment '" - + comment_name + "' for object '" + checkable->GetName() + + commentName + "' for object '" + checkable->GetName() + "'.", additional); } -Dictionary::Ptr ApiActions::RemoveAllComments(const ConfigObject::Ptr& object, - const Dictionary::Ptr& params) -{ - Checkable::Ptr checkable = static_pointer_cast(object); - - if (!checkable) - return ApiActions::CreateResult(404, "Cannot remove comment form non-existent object."); - - checkable->RemoveAllComments(); - - return ApiActions::CreateResult(200, "Successfully removed comments for object '" + checkable->GetName() + "'."); -} - Dictionary::Ptr ApiActions::RemoveComment(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { - if (!params->Contains("name")) - return ApiActions::CreateResult(403, "Parameter 'name' is required."); + Checkable::Ptr checkable = dynamic_pointer_cast(object); - String comment_name = HttpUtility::GetLastParameter(params, "name"); + if (checkable) { + std::set comments = checkable->GetComments(); - Comment::RemoveComment(comment_name); + BOOST_FOREACH(const Comment::Ptr& comment, comments) { + Comment::RemoveComment(comment->GetName()); + } - Comment::Ptr comment = Comment::GetByName(comment_name); + return ApiActions::CreateResult(200, "Successfully removed all comments for object '" + checkable->GetName() + "'."); + } + + Comment::Ptr comment = static_pointer_cast(object); if (!comment) - return ApiActions::CreateResult(200, "Successfully removed comment '" + comment_name + "'."); + return ApiActions::CreateResult(404, "Cannot remove non-existent comment object."); - return ApiActions::CreateResult(403, "Could not remove comment '" + comment_name + "'."); + String commentName = comment->GetName(); + + Comment::RemoveComment(commentName); + + comment = Comment::GetByName(commentName); + + if (comment) + return ApiActions::CreateResult(403, "Could not remove comment '" + commentName + "'."); + + return ApiActions::CreateResult(200, "Successfully removed comment '" + commentName + "'."); } Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, @@ -316,7 +314,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, if (params->Contains("fixed")) fixed = HttpUtility::GetLastParameter(params, "fixed"); - String downtime_name = Downtime::AddDowntime(checkable, + String downtimeName = Downtime::AddDowntime(checkable, HttpUtility::GetLastParameter(params, "author"), HttpUtility::GetLastParameter(params, "comment"), HttpUtility::GetLastParameter(params, "start_time"), @@ -324,46 +322,46 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, HttpUtility::GetLastParameter(params, "trigger_name"), HttpUtility::GetLastParameter(params, "duration")); - Downtime::Ptr downtime = Downtime::GetByName(downtime_name); - int legacy_id = downtime->GetLegacyId(); + Downtime::Ptr downtime = Downtime::GetByName(downtimeName); Dictionary::Ptr additional = new Dictionary(); - additional->Set("name", downtime_name); - additional->Set("legacy_id", legacy_id); + additional->Set("name", downtimeName); + additional->Set("legacy_id", downtime->GetLegacyId()); return ApiActions::CreateResult(200, "Successfully scheduled downtime '" + - downtime_name + "' for object '" + checkable->GetName() + "'.", additional); -} - -Dictionary::Ptr ApiActions::RemoveAllDowntimes(const ConfigObject::Ptr& object, - const Dictionary::Ptr& params) -{ - Checkable::Ptr checkable = static_pointer_cast(object); - - if (!checkable) - return ApiActions::CreateResult(404, "Cannot remove downtime for non-existent object."); - - checkable->RemoveAllDowntimes(); - - return ApiActions::CreateResult(200, "Successfully removed downtimes for object '" + checkable->GetName() + "'."); + downtimeName + "' for object '" + checkable->GetName() + "'.", additional); } Dictionary::Ptr ApiActions::RemoveDowntime(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { - if (!params->Contains("name")) - return ApiActions::CreateResult(403, "Parameter 'name' is required."); + Checkable::Ptr checkable = dynamic_pointer_cast(object); - String downtime_name = HttpUtility::GetLastParameter(params, "name"); + if (checkable) { + std::set downtimes = checkable->GetDowntimes(); - Downtime::RemoveDowntime(downtime_name, true); + BOOST_FOREACH(const Downtime::Ptr& downtime, downtimes) { + Downtime::RemoveDowntime(downtime->GetName(), true); + } - Downtime::Ptr downtime = Downtime::GetByName(downtime_name); + return ApiActions::CreateResult(200, "Successfully removed all downtimes for object '" + checkable->GetName() + "'."); + } + + Downtime::Ptr downtime = static_pointer_cast(object); if (!downtime) - return ApiActions::CreateResult(200, "Successfully removed downtime '" + downtime_name + "'."); + return ApiActions::CreateResult(404, "Cannot remove non-existent downtime object."); - return ApiActions::CreateResult(403, "Could not remove downtime '" + downtime_name + "'."); + String downtimeName = downtime->GetName(); + + Downtime::RemoveDowntime(downtimeName, true); + + downtime = Downtime::GetByName(downtimeName); + + if (downtime) + return ApiActions::CreateResult(403, "Could not remove downtime '" + downtimeName + "'."); + + return ApiActions::CreateResult(200, "Successfully removed downtime '" + downtimeName + "'."); } Dictionary::Ptr ApiActions::ShutdownProcess(const ConfigObject::Ptr& object, diff --git a/lib/icinga/apiactions.hpp b/lib/icinga/apiactions.hpp index a8e012816..f3144b60f 100644 --- a/lib/icinga/apiactions.hpp +++ b/lib/icinga/apiactions.hpp @@ -40,10 +40,8 @@ public: static Dictionary::Ptr AcknowledgeProblem(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); static Dictionary::Ptr RemoveAcknowledgement(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); static Dictionary::Ptr AddComment(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); - static Dictionary::Ptr RemoveAllComments(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); static Dictionary::Ptr RemoveComment(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); static Dictionary::Ptr ScheduleDowntime(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); - static Dictionary::Ptr RemoveAllDowntimes(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); static Dictionary::Ptr RemoveDowntime(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); static Dictionary::Ptr ShutdownProcess(const ConfigObject::Ptr& object, const Dictionary::Ptr& params); static Dictionary::Ptr RestartProcess(const ConfigObject::Ptr& object, const Dictionary::Ptr& params);