Skip to content

Instantly share code, notes, and snippets.

@rtoma
Created March 1, 2017 11:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rtoma/3fb1464de6d8bcf0bc40d55d9e3c0ad5 to your computer and use it in GitHub Desktop.
Save rtoma/3fb1464de6d8bcf0bc40d55d9e3c0ad5 to your computer and use it in GitHub Desktop.
Nagios event broker NEB module for adding a new service without restarting
/*
Proof-of-concept to add services to Nagios without reload/restarts.
By Renzo Toma / 2017-03-01
Tested on Nagios 3.5.1.
New services are not visible using the Nagios CGI scripts as the new services
are missing from the objects.cache file. Workaround: use livestatus + Thruk.
*/
// allow access to service ptr fields
#define NSCORE 1
#include "../include/config.h"
/* include (minimum required) event broker header files */
#include "../include/nebmodules.h"
#include "../include/nebcallbacks.h"
/* include other event broker header files that we need for our work */
#include "../include/nebstructs.h"
#include "../include/broker.h"
/* include some Nagios stuff as well */
#include "../include/config.h"
#include "../include/common.h"
#include "../include/nagios.h"
/* specify event broker API version (required) */
NEB_API_VERSION(CURRENT_NEB_API_VERSION);
void *helloworld_module_handle = NULL;
void helloworld_function(char *);
char *log_prefix = "HELLOWORLD";
int interval = 5; // seconds
int nebmodule_init(int flags, char *args, nebmodule *handle) {
time_t current_time;
/* save our handle */
helloworld_module_handle = handle;
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: module loaded. Build: %s %s", log_prefix, __DATE__, __TIME__);
// register our callback as scheduled event
time(&current_time);
schedule_new_event(EVENT_USER_FUNCTION, TRUE, current_time + interval, TRUE, interval, NULL, TRUE, (void *)helloworld_function, NULL, 0);
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: callback will be executed every %d seconds", log_prefix, interval);
return 0;
}
int nebmodule_deinit(int flags, int reason) {
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: module unloaded", log_prefix);
return 0;
}
void helloworld_function(char *arg) {
char *contactgroup_name = "admins";
char *host_name = "localhost";
char *service_description = "foo";
char *display_name = "foo";
char *check_period = "24x7";
int initial_state = 0;
int max_check_attempts = 4;
int parallelize_check = 1;
int passive_checks_enabled = 1;
double check_interval = 0.5; // 1 = 1 minute
double retry_interval = 0.5;
double notification_interval = 5;
double first_notification_delay = 0;
char *notification_period = "24x7";
int notify_on_recovery = 1;
int notify_on_unknown = 1;
int notify_on_warning = 1;
int notify_on_critical = 1;
int notify_on_flapping = 1;
int notify_on_downtime = 1;
int notifications_enabled = 1;
int is_volatile = 0;
char *event_handler = NULL;
int event_handler_enabled = 1;
char *check_command = "check_local_load!5.0,4.0,3.0!10.0,6.0,4.0";
int active_checks_enabled = 1;
int flap_detection_enabled = 1;
double low_flap_threshold = 0.0;
double high_flap_threshold = 0.0;
int flap_detection_on_ok = 0;
int flap_detection_on_warning = 0;
int flap_detection_on_unknown = 0;
int flap_detection_on_critical = 0;
int stalk_on_ok = 0;
int stalk_on_warning = 0;
int stalk_on_unknown = 0;
int stalk_on_critical = 0;
int process_perf_data = 1;
int failure_prediction_enabled = 1;
char *failure_prediction_options = NULL;
int check_freshness = 0;
int freshness_threshold = 0;
char *notes = NULL;
char *notes_url = NULL;
char *action_url = NULL;
char *icon_image = NULL;
char *icon_image_alt = NULL;
int retain_status_information = 1;
int retain_nonstatus_information = 1;
int obsess_over_service = 1;
// find host by name
host *my_host = find_host(host_name);
if (my_host == NULL) {
logit(NSLOG_RUNTIME_WARNING, TRUE, "%s: host '%s' not found", log_prefix, host_name);
return;
}
// find service
service *my_service = find_service(my_host->name, service_description);
if (my_service != NULL) {
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: service '%s' on host '%s' is present. Last/next check: %d/%d",
log_prefix, my_service->description, my_service->host_name,
my_service->last_check, my_service->next_check);
return;
}
// add service
my_service = add_service(my_host->name, service_description, display_name, check_period, initial_state, max_check_attempts, parallelize_check, passive_checks_enabled, check_interval, retry_interval, notification_interval, first_notification_delay, notification_period, notify_on_recovery, notify_on_unknown, notify_on_warning, notify_on_critical, notify_on_flapping, notify_on_downtime, notifications_enabled, is_volatile, event_handler, event_handler_enabled, check_command, active_checks_enabled, flap_detection_enabled, low_flap_threshold, high_flap_threshold, flap_detection_on_ok, flap_detection_on_warning, flap_detection_on_unknown, flap_detection_on_critical, stalk_on_ok, stalk_on_warning, stalk_on_unknown, stalk_on_critical, process_perf_data, failure_prediction_enabled, failure_prediction_options, check_freshness, freshness_threshold, notes, notes_url, action_url, icon_image, icon_image_alt, retain_status_information, retain_nonstatus_information, obsess_over_service);
if (my_service == NULL) {
logit(NSLOG_RUNTIME_WARNING, TRUE, "%s: can not add service '%s' on host '%s'",
log_prefix, my_host->name, service_description);
return;
}
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: added service '%s' on host '%s'",
log_prefix, my_service->description, my_service->host_name);
// required, otherwise service is not linked to host
my_service->host_ptr = my_host;
// required, otherwise service view in thruk does not work
add_service_link_to_host(my_host, my_service);
char *command_buf = (char *)strdup(check_command);
char *command_name = strtok(command_buf, "!");
command *temp_command = find_command(command_name);
if (temp_command == NULL) {
logit(NSLOG_RUNTIME_WARNING, TRUE, "%s: can not find check command '%s'",
log_prefix, command_name);
return;
}
// required, otherwise check stays in pending
my_service->check_command_ptr = temp_command;
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: check command '%s' verified & linked",
log_prefix, command_name);
// add contactgroup to service
contactgroupsmember *temp_contactgroupsmember = add_contactgroup_to_service(my_service, contactgroup_name);
if (temp_contactgroupsmember == NULL) {
logit(NSLOG_RUNTIME_WARNING, TRUE, "%s: can not add contactgroup '%s'",
log_prefix, contactgroup_name);
return;
}
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: contactgroup '%s' was added to service",
log_prefix, contactgroup_name);
timeperiod *temp_timeperiod = NULL;
temp_timeperiod = find_timeperiod(my_service->check_period);
if(temp_timeperiod == NULL) {
logit(NSLOG_RUNTIME_WARNING, TRUE, "%s: can not find check period '%s'",
log_prefix, my_service->check_period);
return;
}
// required, otherwise rescheduling does not work
my_service->check_period_ptr = temp_timeperiod;
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: check period '%s' verified & linked",
log_prefix, my_service->check_period);
// schedule for near future
time_t preferred_time = time(0) + 10;
schedule_service_check(my_service, preferred_time, CHECK_OPTION_NONE);
logit(NSLOG_INFO_MESSAGE, TRUE, "%s: service has been scheduled", log_prefix);
return;
}
@rtoma
Copy link
Author

rtoma commented Mar 1, 2017

Thruk screenshot showing the 'foo' service:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment