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

enh(centengine) : add Acknowledge Problem #54

Merged
merged 2 commits into from
Jul 17, 2020
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
4 changes: 2 additions & 2 deletions include/com/centreon/engine/broker.hh
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@ void broker_acknowledgement_data(int type,
int attr,
int acknowledgement_type,
void* data,
char* ack_author,
char* ack_data,
const char* ack_author,
const char* ack_data,
int subtype,
int notify_contacts,
int persistent_comment,
Expand Down
6 changes: 6 additions & 0 deletions include/com/centreon/engine/engine_impl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ class engine_impl final : public Engine::Service {
grpc::Status RemoveServiceAcknowledgement(grpc::ServerContext* context,
const ServiceIdentifier* request,
CommandSuccess* response) override;
grpc::Status AcknowledgementHostProblem(grpc::ServerContext* context,
const EngineAcknowledgement* request,
CommandSuccess* response) override;
grpc::Status AcknowledgementServiceProblem(grpc::ServerContext* context,
const EngineAcknowledgement* request,
CommandSuccess* response) override;
grpc::Status ScheduleHostDowntime(grpc::ServerContext* context,
const ScheduleDowntimeIdentifier* request,
CommandSuccess* response) override;
Expand Down
4 changes: 2 additions & 2 deletions include/com/centreon/engine/nebstructs.hh
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ typedef struct nebstruct_acknowledgement_struct {
uint64_t host_id;
uint64_t service_id;
int state;
char* author_name;
char* comment_data;
const char* author_name;
const char* comment_data;
int is_sticky;
int persistent_comment;
int notify_contacts;
Expand Down
4 changes: 2 additions & 2 deletions src/cce_core/broker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ void broker_acknowledgement_data(int type,
int attr,
int acknowledgement_type,
void* data,
char* ack_author,
char* ack_data,
const char* ack_author,
const char* ack_data,
int subtype,
int notify_contacts,
int persistent_comment,
Expand Down
18 changes: 18 additions & 0 deletions src/cce_rpc/engine.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ service Engine {
rpc RemoveHostAcknowledgement(HostIdentifier) returns (CommandSuccess) {}
rpc RemoveServiceAcknowledgement(ServiceIdentifier)
returns (CommandSuccess) {}
rpc AcknowledgementHostProblem(EngineAcknowledgement)
returns (CommandSuccess) {}
rpc AcknowledgementServiceProblem(EngineAcknowledgement)
returns (CommandSuccess) {}
rpc DeleteHostDowntime(GenericValue) returns (CommandSuccess) {}
rpc DeleteServiceDowntime(GenericValue) returns (CommandSuccess) {}
rpc DeleteHostDowntimeFull(DowntimeCriterias) returns (CommandSuccess) {}
Expand Down Expand Up @@ -437,3 +441,17 @@ message EngineSignalProcess {
Process process = 1;
uint32 scheduled_time = 2;
}

message EngineAcknowledgement {
string host_name = 1;
string service_desc = 2;
string ack_author = 3;
string ack_data = 4;
enum Type {
NORMAL = 0;
STICKY = 1;
}
Type type = 5;
bool notify = 6;
bool persistent = 7;
}
117 changes: 115 additions & 2 deletions src/centengine/engine_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* For more information : contact@centreon.com
*
*/

#include "com/centreon/engine/engine_impl.hh"

#include <google/protobuf/util/time_util.h>
Expand All @@ -27,6 +26,7 @@
#include <future>

#include "com/centreon/engine/anomalydetection.hh"
#include "com/centreon/engine/broker.hh"
#include "com/centreon/engine/command_manager.hh"
#include "com/centreon/engine/comment.hh"
#include "com/centreon/engine/common.hh"
Expand Down Expand Up @@ -133,7 +133,7 @@ grpc::Status engine_impl::GetHost(grpc::ServerContext* context
host->set_address(selectedhost->get_address());
host->set_check_period(selectedhost->get_check_period());
host->set_current_state(
static_cast<EngineHost::tate>(selectedhost->get_current_state()));
static_cast<EngineHost::State>(selectedhost->get_current_state()));
host->set_id(selectedhost->get_host_id());
return 0;
});
Expand Down Expand Up @@ -792,6 +792,119 @@ grpc::Status engine_impl::RemoveServiceAcknowledgement(
return grpc::Status::OK;
}

grpc::Status engine_impl::AcknowledgementHostProblem(
grpc::ServerContext* context __attribute__((unused)),
const EngineAcknowledgement* request,
CommandSuccess* response) {
auto fn = std::packaged_task<int32_t(void)>([request]() -> int32_t {
std::shared_ptr<engine::host> temp_host;
/* get the host */
auto it = host::hosts.find(request->host_name());
if (it != host::hosts.end())
temp_host = it->second;
if (temp_host == nullptr)
return 1;
/* cannot acknowledge a non-existent problem */
if (temp_host->get_current_state() == host::state_up)
return 1;
/* set the acknowledgement flag */
temp_host->set_problem_has_been_acknowledged(true);
/* set the acknowledgement type */
if (EngineAcknowledgement::Type_Name(request->type()) == "STICKY")
temp_host->set_acknowledgement_type(ACKNOWLEDGEMENT_STICKY);
else
temp_host->set_acknowledgement_type(ACKNOWLEDGEMENT_NORMAL);
/* schedule acknowledgement expiration */
time_t current_time(time(nullptr));
temp_host->set_last_acknowledgement(current_time);
temp_host->schedule_acknowledgement_expiration();
/* send data to event broker */
broker_acknowledgement_data(
NEBTYPE_ACKNOWLEDGEMENT_ADD, NEBFLAG_NONE, NEBATTR_NONE,
HOST_ACKNOWLEDGEMENT, static_cast<void*>(temp_host.get()),
request->ack_author().c_str(), request->ack_data().c_str(),
request->type(), request->notify(), request->persistent(), nullptr);
/* send out an acknowledgement notification */
if (request->notify())
temp_host->notify(notifier::reason_acknowledgement, request->ack_author(),
request->ack_data(),
notifier::notification_option_none);
/* update the status log with the host info */
temp_host->update_status(false);
/* add a comment for the acknowledgement */
auto com = std::make_shared<comment>(
comment::host, comment::acknowledgment, temp_host->get_host_id(), 0,
current_time, request->ack_author(), request->ack_data(),
request->persistent(), comment::internal, false, (time_t)0);
comment::comments.insert({com->get_comment_id(), com});

return 0;
});

std::future<int32_t> result = fn.get_future();
command_manager::instance().enqueue(std::move(fn));

response->set_value(!result.get());
return grpc::Status::OK;
}

grpc::Status engine_impl::AcknowledgementServiceProblem(
grpc::ServerContext* context __attribute__((unused)),
const EngineAcknowledgement* request,
CommandSuccess* response) {
auto fn = std::packaged_task<int32_t(void)>([request]() -> int32_t {
std::shared_ptr<engine::service> temp_service;
auto it =
service::services.find({request->host_name(), request->service_desc()});
if (it != service::services.end())
temp_service = it->second;
if (temp_service == nullptr)
return 1;
/* cannot acknowledge a non-existent problem */
if (temp_service->get_current_state() == service::state_ok)
return 1;
/* set the acknowledgement flag */
temp_service->set_problem_has_been_acknowledged(true);
/* set the acknowledgement type */
if (EngineAcknowledgement::Type_Name(request->type()) == "STICKY")
temp_service->set_acknowledgement_type(ACKNOWLEDGEMENT_STICKY);
else
temp_service->set_acknowledgement_type(ACKNOWLEDGEMENT_NORMAL);
/* schedule acknowledgement expiration */
time_t current_time(time(nullptr));
temp_service->set_last_acknowledgement(current_time);
temp_service->schedule_acknowledgement_expiration();
/* send data to event broker */
broker_acknowledgement_data(
NEBTYPE_ACKNOWLEDGEMENT_ADD, NEBFLAG_NONE, NEBATTR_NONE,
SERVICE_ACKNOWLEDGEMENT, static_cast<void*>(temp_service.get()),
request->ack_author().c_str(), request->ack_data().c_str(),
request->type(), request->notify(), request->persistent(), nullptr);
/* send out an acknowledgement notification */
if (request->notify())
temp_service->notify(notifier::reason_acknowledgement,
request->ack_author(), request->ack_data(),
notifier::notification_option_none);
/* update the status log with the service info */
temp_service->update_status(false);

/* add a comment for the acknowledgement */
auto com = std::make_shared<comment>(
comment::service, comment::acknowledgment, temp_service->get_host_id(),
temp_service->get_service_id(), current_time, request->ack_author(),
request->ack_data(), request->persistent(), comment::internal, false,
(time_t)0);
comment::comments.insert({com->get_comment_id(), com});
return 0;
});

std::future<int32_t> result = fn.get_future();
command_manager::instance().enqueue(std::move(fn));

response->set_value(!result.get());
return grpc::Status::OK;
}

/**
* @brief Schedules downtime for a specific host.
*
Expand Down
83 changes: 82 additions & 1 deletion tests/engine/enginerpc/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,60 @@ class EngineRPCClient {
return true;
}

bool AcknowledgementHostProblem(std::string const& hostname,
std::string const& ackauthor,
std::string const& ackdata,
int type,
bool notify,
bool persistent,
CommandSuccess* response) {
EngineAcknowledgement request;
grpc::ClientContext context;
request.set_host_name(hostname);
request.set_ack_author(ackauthor);
request.set_ack_data(ackdata);
request.set_type(static_cast<EngineAcknowledgement::Type>(type));
request.set_notify(notify);
request.set_persistent(persistent);

grpc::Status status =
_stub->AcknowledgementHostProblem(&context, request, response);
if (!status.ok()) {
std::cout << "AcknowledgementHostProblem rpc engine failed"
<< std::endl;
return false;
}
return true;
}

bool AcknowledgementServiceProblem(std::string const& hostname,
std::string const& servicedesc,
std::string const& ackauthor,
std::string const& ackdata,
int type,
bool notify,
bool persistent,
CommandSuccess* response) {
EngineAcknowledgement request;
grpc::ClientContext context;
request.set_host_name(hostname);
request.set_service_desc(servicedesc);
request.set_ack_author(ackauthor);
request.set_ack_data(ackdata);
request.set_type(static_cast<EngineAcknowledgement::Type>(type));
request.set_notify(notify);
request.set_persistent(persistent);

grpc::Status status =
_stub->AcknowledgementServiceProblem(&context, request, response);
if (!status.ok()) {
std::cout << "AcknowledgementServiceProblem rpc engine failed"
<< std::endl;
return false;
}
return true;
}

bool ScheduleHostDowntime(std::string const& hostname,
std::string const& hostgroupname,
std::string const& servicegroupname,
Expand Down Expand Up @@ -1733,9 +1787,36 @@ int main(int argc, char** argv) {

status = client.SignalProcess(process, scheduledtime, &response);
std::cout << "SignalProcess" << std::endl;
} else if (strcmp(argv[1], "AcknowledgementHostProblem") == 0) {
CommandSuccess response;
std::string hostname(argv[2]);
std::string ackauthor(argv[3]);
std::string ackdata(argv[4]);
int type = atoi(argv[5]);
bool notify = atoi(argv[6]);
bool persistent = atoi(argv[7]);

status = client.AcknowledgementHostProblem(hostname, ackauthor,
ackdata, type, notify, persistent, &response);
std::cout << "AcknowledgementHostProblem" << std::endl;
} else if (strcmp(argv[1], "AcknowledgementServiceProblem") == 0) {
CommandSuccess response;
std::string hostname(argv[2]);
std::string servicedesc(argv[3]);
std::string ackauthor(argv[4]);
std::string ackdata(argv[5]);
int type = atoi(argv[6]);
bool notify = atoi(argv[7]);
bool persistent = atoi(argv[8]);

status = client.AcknowledgementServiceProblem(hostname, servicedesc, ackauthor,
ackdata, type, notify, persistent, &response);
std::cout << "AcknowledgementServiceProblem" << std::endl;
}

else
else {
std::cout << "unknown command" << std::endl;
status = EXIT_FAILURE;
}
exit(status);
}
52 changes: 51 additions & 1 deletion tests/engine/enginerpc/enginerpc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class EngineRpc : public TestEngine {

host_map const& hm{engine::host::hosts};
_host = hm.begin()->second;
_host->set_current_state(engine::host::state_up);
_host->set_current_state(engine::host::state_down);
_host->set_state_type(checkable::hard);
_host->set_problem_has_been_acknowledged(false);
_host->set_notify_on(static_cast<uint32_t>(-1));
Expand All @@ -144,6 +144,10 @@ class EngineRpc : public TestEngine {
else
_svc = svc;
}
_svc->set_current_state(engine::service::state_critical);
_svc->set_state_type(checkable::hard);
_svc->set_problem_has_been_acknowledged(false);
_svc->set_notify_on(static_cast<uint32_t>(-1));

contact_map const& cm{engine::contact::contacts};
_contact = cm.begin()->second;
Expand Down Expand Up @@ -770,6 +774,52 @@ TEST_F(EngineRpc, RemoveServiceAcknowledgement) {
erpc.shutdown();
}

TEST_F(EngineRpc, AcknowledgementHostProblem) {
enginerpc erpc("0.0.0.0", 40001);
std::unique_ptr<std::thread> th;
std::condition_variable condvar;
std::mutex mutex;
bool continuerunning = false;

ASSERT_EQ(_host->get_problem_has_been_acknowledged(), false);
call_command_manager(th, &condvar, &mutex, &continuerunning);

auto output = execute("AcknowledgementHostProblem test_host admin test 1 0 0");
{
std::lock_guard<std::mutex> lock(mutex);
continuerunning = true;
}
condvar.notify_one();
th->join();

ASSERT_EQ(_host->get_problem_has_been_acknowledged(), true);
erpc.shutdown();
}

TEST_F(EngineRpc, AcknowledgementServiceProblem) {
enginerpc erpc("0.0.0.0", 40001);
std::unique_ptr<std::thread> th;
std::condition_variable condvar;
std::mutex mutex;
bool continuerunning = false;

ASSERT_EQ(_svc->get_problem_has_been_acknowledged(), false);
call_command_manager(th, &condvar, &mutex, &continuerunning);

auto output = execute("AcknowledgementServiceProblem test_host test_svc admin test 1 0 0");
;
{
std::lock_guard<std::mutex> lock(mutex);
continuerunning = true;
}
condvar.notify_one();
th->join();

ASSERT_EQ(_svc->get_problem_has_been_acknowledged(), true);
erpc.shutdown();
}


TEST_F(EngineRpc, ScheduleHostDowntime) {
enginerpc erpc("0.0.0.0", 40001);
std::unique_ptr<std::thread> th;
Expand Down