Host per Popup-Skript aus der Zabbix-Server Weboberfläche in Wartung setzen: Unterschied zwischen den Versionen
Aus znilwiki
BLinz (Diskussion | Beiträge) |
BLinz (Diskussion | Beiträge) |
||
(11 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
<u>'''Changelog:'''</u> | |||
* 2017 - 2024 diverse Änderungen | |||
* 25.08.2024: Anpassung des Skriptes wegen "Bearer" | |||
---- | |||
[[Kategorie:Zabbix]] | [[Kategorie:Zabbix]] | ||
==Vorwort== | ==Vorwort== | ||
Zeile 295: | Zeile 298: | ||
===Skript auf Zabbix Server hinterlegen=== | ===Skript auf Zabbix Server hinterlegen=== | ||
{{Hinweis| Ich habe das Skript am 25.08.2024 an Zabbix 7.0 angepasst. Zum einen habe ich die Zeichenfolge "Bearer" von der Tokenangabe zu den Befehlsaufrufen verlegt.<br> | |||
Außerdem habe ich das Löschen der Wartungspläne anpasst. Der API-Aufruf *****maintenance.get***** kann scheinbar nichts mehr mit der HostId anfangen. Ich habe das deshlab auf eine Volltextsuche in der Beschreibung umgestellt, dort setzt dieses Skript auch immer den Hostnamen ein}}<br> | |||
Erstellt im <code>externalscripts</code> Verzeichnis von Zabbix das folgende Skript:<br> | Erstellt im <code>externalscripts</code> Verzeichnis von Zabbix das folgende Skript:<br> | ||
nano /usr/lib/zabbix/externalscripts/zabbix_main_host.pl | nano /usr/lib/zabbix/externalscripts/zabbix_main_host.pl | ||
Zeile 304: | Zeile 309: | ||
use vars qw/ %opt /; | use vars qw/ %opt /; | ||
my $url = " | my $url = "http://localhost/api_jsonrpc.php"; # change <localhost> to your Zabbix WEB-FRONTEND Server if different!!!! | ||
my $apitoken=" | my $apitoken="euerapitoken"; | ||
my $maintenanceid; | my $maintenanceid; | ||
Zeile 314: | Zeile 319: | ||
my $hostname = $opt{s}; | my $hostname = $opt{s}; | ||
my $duration = $opt{d} || 10800; | my $duration = $opt{d} || 10800; | ||
my $maintname = $opt{n}; | my $maintname = $opt{n}; | ||
# Authenticate against Zabbix for API Maintenance addition | # Authenticate against Zabbix for API Maintenance addition | ||
Zeile 345: | Zeile 350: | ||
print STDERR << "EOF"; | print STDERR << "EOF"; | ||
usage: $0 [-hr] -s hostname [-d duration] -n name | usage: $0 [-hr] -s hostname [-d duration] -n name | ||
-h : This (help) message | -h : This (help) message | ||
-r : Remove maintenance for specified host | -r : Remove maintenance for specified host | ||
-s hostname : Hostname in Zabbix | -s hostname : Hostname in Zabbix | ||
-d : Duration of maintenance in seconds. Leave blank to use default. | -d : Duration of maintenance in seconds. Leave blank to use default. | ||
Zeile 356: | Zeile 361: | ||
-s and -n are required | -s and -n are required | ||
example: $0 -s hostname -d 3600 -n backup | example: $0 -s hostname -d 3600 -n backup | ||
example: $0 -s hostname -r -n backup | example: $0 -s hostname -r -n backup | ||
Zeile 390: | Zeile 395: | ||
sub gethostid{ | sub gethostid{ | ||
my $hostname = shift; | my $hostname = shift; | ||
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: $apitoken' -d '{ | my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: Bearer $apitoken' -d '{ | ||
"params": { | "params": { | ||
"filter": { | "filter": { | ||
Zeile 431: | Zeile 436: | ||
my $hostid = shift; | my $hostid = shift; | ||
my $maintname = shift; | my $maintname = shift; | ||
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: $apitoken' -d '{ | my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: Bearer $apitoken' -d '{ | ||
"params": { | "params": { | ||
"output": "extend", | "output": "extend", | ||
"selectHosts": "refer", | "selectHosts": "refer", | ||
"selectGroups": "refer", | "selectGroups": "refer", | ||
" | "search": { | ||
"description": "*$hostname*" | |||
}, | |||
"searchWildcardsEnabled": true, | |||
"searchByAny": true | |||
}, | }, | ||
"jsonrpc": "2.0", | "jsonrpc": "2.0", | ||
"method": "maintenance.get", | "method": "maintenance.get", | ||
"id": 2 }' $url); | "id": 2 }' $url); | ||
my $res = `$process`; | my $res = `$process`; | ||
print($res); | |||
chomp($res); | chomp($res); | ||
my @output = split(/,/,$res); | my @output = split(/,/,$res); | ||
my $x=0; | my $x=0; | ||
Zeile 464: | Zeile 474: | ||
} | } | ||
} | } | ||
################################################# | ################################################# | ||
# Subroutine to add maintenance window to Zabbix | # Subroutine to add maintenance window to Zabbix | ||
Zeile 476: | Zeile 485: | ||
my $end = ($start + $duration); | my $end = ($start + $duration); | ||
# my $auth = newrequest($url, $apiuser, $apipassword); | # my $auth = newrequest($url, $apiuser, $apipassword); | ||
my $process = 'curl -k -s -i -X POST -H \'Content-Type: application/json-rpc\' -H \'Authorization: '.$apitoken.'\' -d "{ | my $process = 'curl -k -s -i -X POST -H \'Content-Type: application/json-rpc\' -H \'Authorization: Bearer '.$apitoken.'\' -d "{ | ||
\"jsonrpc\":\"2.0\", | \"jsonrpc\":\"2.0\", | ||
\"method\":\"maintenance.create\", | \"method\":\"maintenance.create\", | ||
Zeile 492: | Zeile 501: | ||
\"period\": '.$duration.'}] | \"period\": '.$duration.'}] | ||
}], | }], | ||
\"id\":3}" '.$url; | \"id\":3}" '.$url; | ||
my $res = `$process`; | my $res = `$process`; | ||
chomp($res); | chomp($res); | ||
my @output = split(/,/,$res); | my @output = split(/,/,$res); | ||
foreach(@output){ | foreach(@output){ | ||
if ($_ =~ m/\"error/){ | if ($_ =~ m/\"error/){ | ||
Zeile 505: | Zeile 514: | ||
print "$_\n" if ($_ =~ m/\"result/); | print "$_\n" if ($_ =~ m/\"result/); | ||
} | } | ||
} | } | ||
################################################# | ################################################# | ||
Zeile 512: | Zeile 521: | ||
sub remmaint{ | sub remmaint{ | ||
$maintenanceid = shift; | $maintenanceid = shift; | ||
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: $apitoken' -d '{ | my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: Bearer $apitoken' -d '{ | ||
"jsonrpc":"2.0", | "jsonrpc":"2.0", | ||
"method":"maintenance.delete", | "method":"maintenance.delete", | ||
"params":["$maintenanceid"], | "params":["$maintenanceid"], | ||
"id":2}' $url); | "id":2}' $url); | ||
my $res = `$process`; | my $res = `$process`; | ||
chomp($res); | chomp($res); | ||
my @output = split(/,/,$res); | my @output = split(/,/,$res); | ||
foreach(@output){ | foreach(@output){ | ||
print "$_\n" if ($_ =~ m/\"error/); | print "$_\n" if ($_ =~ m/\"error/); | ||
Zeile 531: | Zeile 540: | ||
Das Skript stammt fast 1:1 von https://www.zabbix.org/wiki/Perl_script_to_add/remove_Maintenance<br> | Das Skript stammt fast 1:1 von https://www.zabbix.org/wiki/Perl_script_to_add/remove_Maintenance<br> | ||
Ich habe es an die neueren Zabbix-Versionen angepasst bzw. die Host-Abfrage repariert sowie das es selbst signierte Zertifikate ignoriert.<br> | Ich habe es an die neueren Zabbix-Versionen angepasst bzw. die Host-Abfrage repariert sowie das es selbst signierte Zertifikate ignoriert.<br> | ||
Dank an '''Christoph Schmocker''' welcher | Dank an '''Christoph Schmocker''' welcher die Idee für die Anpassung an die neuen API-Token geleifert hat!<br> | ||
<br> | <br> | ||
Ihr müsst in dem Skript die folgenden Zeilen anpassen:<br> | Ihr müsst in dem Skript die folgenden Zeilen anpassen:<br> | ||
Zeile 547: | Zeile 556: | ||
==Skripts in Zabbix hinterlegen== | ==Skripts in Zabbix hinterlegen== | ||
Die Skripts findet Ihr unter<br> | Die Skripts findet Ihr unter<br> | ||
Bis Zabbix 6.2:br> | |||
[[Datei:ClipCapIt-170620-202133.PNG]]<br> | [[Datei:ClipCapIt-170620-202133.PNG]]<br> | ||
<br> | <br> | ||
Ab Zabbix 6.4:<br> | |||
:[[Datei:ClipCapIt-240825-135912.PNG]]<br> | :[[Datei:ClipCapIt-240825-135912.PNG]]<br> | ||
<br> | <br> | ||
===Wartung für Zeitraum X=== | ===Wartung für Zeitraum X=== | ||
Unter | Unter (bis Zabbix 6.2)<br> | ||
Administration ==> Scripts | Administration ==> Scripts | ||
bzw.<br> | bzw. ab Zabbix 6.4<br> | ||
Alerts ==> Scripts | Alerts ==> Scripts | ||
legen wir ein neues Script an: | legen wir ein neues Script an: | ||
Bis Zabbix 6.2:<br> | |||
Name : Maintenance/1h | Name : Maintenance/1h | ||
Type : Script | Type : Script | ||
Execute on: Zabbix Server | Execute on: Zabbix Server | ||
Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s {HOST.HOST} -d 3600 -n via_Popup_Menu 2>&1 | Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -d 3600 -n via_Popup_Menu 2>&1 | ||
Ab Zabbix 6.4:<br> | |||
Name : 1h | |||
Scope : Manual host action | |||
Menu path : Maintenance | |||
Type : Script | |||
Execute on: Zabbix Server | |||
Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -d 3600 -n via_Popup_Menu 2>&1 | |||
Am Ende sollte das so aussehen:<br> | Am Ende sollte das so aussehen:<br> | ||
Bis Zabbix 6.2:<br> | |||
[[Datei:ClipCapIt-170620-202324.PNG]]<br> | [[Datei:ClipCapIt-170620-202324.PNG]]<br> | ||
Ab Zabbix 6.4:<br> | |||
:[[Datei:ClipCapIt-240825-152409.PNG]]<br> | |||
Unten könnte Ihr noch die Berechtigungen einstellen - so können auch Read-Only Benutzer einen Host in den Wartungsmodus setzen.<br> | Unten könnte Ihr noch die Berechtigungen einstellen - so können auch Read-Only Benutzer einen Host in den Wartungsmodus setzen.<br> | ||
Das Skript könnt Ihr mehrmals klonen, ändert im Namen das 1h in den gewünschten Zeitraum, z.B. 4h und im Aufruf die 3600 auf die entsprechende Anzahl der Sekunden, z.B. 14400. | Das Skript könnt Ihr mehrmals klonen, ändert im Namen das 1h in den gewünschten Zeitraum, z.B. 4h und im Aufruf die 3600 auf die entsprechende Anzahl der Sekunden, z.B. 14400. | ||
Zeile 572: | Zeile 594: | ||
===Wartung löschen=== | ===Wartung löschen=== | ||
Diese Script löscht alle(!) zuvor erstellten Wartungspläne für den Host, egal ob noch gültig oder abgelaufen, die mit diesem Script erstellt wurden.<br> | Diese Script löscht alle(!) zuvor erstellten Wartungspläne für den Host, egal ob noch gültig oder abgelaufen, die mit diesem Script erstellt wurden.<br> | ||
Bis Zabbix 6.2: | |||
Name : Maintenance/Delete All | Name : Maintenance/Delete All | ||
Type : Script | Type : Script | ||
Execute on: Zabbix Server | Execute on: Zabbix Server | ||
Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s {HOST.HOST} -r -n via_Popup_Menu 2>&1 | Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -r -n via_Popup_Menu 2>&1 | ||
<br> | <br> | ||
[[Datei:ClipCapIt-170620-202634.PNG]]<br> | [[Datei:ClipCapIt-170620-202634.PNG]]<br> | ||
<br> | |||
Ab Zabbix 6.4:<br> | |||
Name : Delete All | |||
Scope : Manual host action | |||
Menu path : Maintenance | |||
Type : Script | |||
Execute on: Zabbix Server | |||
Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -r -n via_Popup_Menu 2>&1 | |||
<br> | |||
:[[Datei:ClipCapIt-240825-152517.PNG]]<br> | |||
<br> | <br> | ||
<br> | <br> |
Aktuelle Version vom 25. August 2024, 15:31 Uhr
Changelog:
- 2017 - 2024 diverse Änderungen
- 25.08.2024: Anpassung des Skriptes wegen "Bearer"
Vorwort
Nachfolgend wird beschrieben wie man direkt aus der Weboberfläche von Zabbix aus dem Submenü / Popupmenü eines Hosts diesen in den Wartungsmodus versetzt.
Das tolle daran ist das man so auch "Read-Only" Benutzern die Möglichkeit geben kann, einen Host (den er sehen kann) in den Wartungsmodus zu versetzen.
Es gibt hierbei 2 verschiedene Vorgehensweisen - bis Zabbix 5.0 und ab Zabbix 5.2 - bitte drauf achten!
Bis Zabbix 5.0 (per Benutzername und Passwort)
Benutzer für Skript anlegen
Erstellt einen neuen Superadmin Benutzer in Zabbix, das Passwort am besten nur Buchstaben und Zahlen.
Benutzer : setmaintenance Passwort : abc123 Gruppen : Zabbix administrators User type: Zabbix Super Admin
Falls Ihr LDAP-Authentifizierung nutzt sollte der Benutzer in die "noLDAP" Gruppe.
Skript auf Zabbix Server hinterlegen
Erstellt im externalscripts
Verzeichnis von Zabbix das folgende Skript:
nano /usr/lib/zabbix/externalscripts/zabbix_main_host.pl
Den genauen Pfad findet Ihr in der zabbix_server.conf
#!/usr/bin/perl
use strict;
use Getopt::Std;
use vars qw/ %opt /;
my $url = "http://localhost/api_jsonrpc.php"; # change <localhost> to your Zabbix WEB-FRONTEND Server if different!!!!
my $apiuser="setmaintenance"; # API User's Username
my $apipassword="abc123"; # API User's password
my $maintenanceid;
#############
# Begin main
#
init();
my $hostname = $opt{s};
my $duration = $opt{d} || 10800;
my $maintname = $opt{n};
# Authenticate against Zabbix for API Maintenance addition
my $auth = newrequest($url, $apiuser, $apipassword);
my $hostid = gethostid($hostname);
if($opt{r}){
print "Removing maintenance for host $hostname\n";
getmaintid($hostid,$maintname);
exit(0);
}else{
print "Adding maintenance for host $hostname\n";
addmaint($hostid,$duration,$maintname);
}
exit(0);
#########################
# Get command line input
#
sub init(){
my $opt_string = 'hrs:d:n:';
getopts( "$opt_string", \%opt ) or usage();
usage() if $opt{h};
usage() if !$opt{s};
usage() if !$opt{n};
}
#####################
# Print script usage
#
sub usage(){
print STDERR << "EOF";
usage: $0 [-hr] -s hostname [-d duration] -n name
-h : This (help) message
-r : Remove maintenance for specified host
-s hostname : Hostname in Zabbix
-d : Duration of maintenance in seconds. Leave blank to use default.
300 = 5 minutes
1800 = 30 minutes
3600 = 1 hour
10800 = 3 hour (default)
-n name : unique identifier
-s and -n are required
example: $0 -s hostname -d 3600 -n backup
example: $0 -s hostname -r -n backup
EOF
exit;
}
#############################################
# Zabbix API requests require authentication
#
sub newrequest {
my ($url, $user, $password) = @_;
my $authenticate = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
"params": {
"password": "$password",
"user": "$user"
},
"jsonrpc": "2.0",
"method": "user.login",
"id": 0
}' $url | grep result | head -n 1 | cut -d '"' -f 8);
my $auth = `$authenticate`;
chomp($auth);
return $auth
}
###################################################
# Subroutine to query Zabbix to get host id
#
sub gethostid{
my $hostname = shift;
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
"params": {
"filter": {
"name": "$hostname"
}
},
"jsonrpc": "2.0",
"method": "host.get",
"auth": "$auth",
"id": 2 }' $url);
my $res = `$process`;
chomp($res);
# print "$res \n\n";
my @output = split(/,/,$res);
my $x=0;
foreach(@output){
if (($output[$x] =~ m/\"host\"/)&&($output[$x] =~ m/$hostname/)){
$output[$x-2] =~ s/\[\{//g;
$output[$x-2] =~ s/"//g;
$output[$x-2] =~ s/hostid://g;
$output[$x-2] =~ s/result://g;
$output[$x-2] =~ s/\{//g;
$hostid = $output[$x-2];
}
$x++;
}
if(!$hostid){
print "WARNING - $hostname not found in maintenance for Zabbix.\n";
exit(1);
}
print "Host ID: ".$hostid."\n";
return $hostid
}
###################################################
# Subroutine to query Zabbix to get maintenance id
#
sub getmaintid{
my $hostid = shift;
my $maintname = shift;
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
"params": {
"output": "extend",
"selectHosts": "refer",
"selectGroups": "refer",
"hostids": "$hostid"
},
"jsonrpc": "2.0",
"method": "maintenance.get",
"auth": "$auth",
"id": 2 }' $url);
my $res = `$process`;
chomp($res);
my @output = split(/,/,$res);
my $x=0;
foreach(@output){
if (($output[$x] =~ m/\"name\"/)&&($output[$x] =~ m/ID $maintname/)){
$output[$x-1] =~ s/\[\{//g;
$output[$x-1] =~ s/"//g;
$output[$x-1] =~ s/maintenanceid://g;
$output[$x-1] =~ s/result://g;
$output[$x-1] =~ s/\{//g;
$maintenanceid = $output[$x-1];
remmaint($maintenanceid);
}
$x++;
}
if(!$maintenanceid){
print "WARNING - $hostname not found in maintenance for Zabbix.\n";
exit(1);
}
}
#################################################
# Subroutine to add maintenance window to Zabbix
#
sub addmaint{
$hostid = shift;
$duration = shift;
$maintname = shift;
my $start = time();
my $end = ($start + $duration);
# my $auth = newrequest($url, $apiuser, $apipassword);
my $process = 'curl -k -s -i -X POST -H \'Content-Type: application/json-rpc\' -d "{
\"jsonrpc\":\"2.0\",
\"method\":\"maintenance.create\",
\"params\":[{
\"groupids\":[],
\"hostids\":[\"'.$hostid.'\"],
\"name\":\"000_Manually Maintenance Mode with ID '.$maintname.' - '.$start.'\",
\"maintenance_type\":\"0\",
\"description\":\"000_Manually Maintenance Mode for '.$hostname.' set by Linux-Admin\",
\"active_since\":\"'.$start.'\",
\"active_till\":\"'.$end.'\",
\"timeperiods\": [{
\"timeperiod_type\": 0,
\"start_date\": \"'.$start.'\",
\"period\": '.$duration.'}]
}],
\"auth\":\"'.$auth.'\",
\"id\":3}" '.$url;
my $res = `$process`;
chomp($res);
my @output = split(/,/,$res);
foreach(@output){
if ($_ =~ m/\"error/){
print "$_\n";
exit(1);
}
print "$_\n" if ($_ =~ m/\"result/);
}
}
#################################################
# Subroutine to remove maintenance window from Zabbix
#
sub remmaint{
$maintenanceid = shift;
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
"jsonrpc":"2.0",
"method":"maintenance.delete",
"params":["$maintenanceid"],
"auth":"$auth",
"id":2}' $url);
my $res = `$process`;
chomp($res);
my @output = split(/,/,$res);
foreach(@output){
print "$_\n" if ($_ =~ m/\"error/);
print "$_\n" if ($_ =~ m/\"result/);
}
}
Das Skript stammt fast 1:1 von https://www.zabbix.org/wiki/Perl_script_to_add/remove_Maintenance
Ich habe es an die neueren Zabbix-Versionen angepasst bzw. die Host-Abfrage repariert.
Außerdem ignoriert es nun selbst signierte Zertifikate.
Ihr müsst in dem Skript die folgenden Zeilen anpassen:
my $url = "http://localhost/api_jsonrpc.php"; # change <zabbix server> to your zabbix server my $apiuser="setmaintance"; # API User's Username my $apipassword="abc123"; # API User's password
mit euren Daten. Die URL ist auf localhost
, das sollte immer passen. Ggf. muss das auf localhost/zabbix
geändert werden (je nachdem wie der Aufruf eures Zabbix Servers ist.
Wenn das Webinterface von Zabbix auf einem separaten Server installiert ist sollte ihr den entsprechenden DNS-Namen oder die IP dieses Servers eintragen. Das Skript selbst muss aber immer auf dem Zabbix-Server liegen.
Und ggf. https statt http
Im Anschluß müsst Ihr das Skript noch ausführbar machen:
chmod +x /usr/lib/zabbix/externalscripts/zabbix_main_host.pl
Weiter geht es bei
Jetzt geht es weiter mit #Skripts in Zabbix hinterlegen
Ab Zabbix 6.2 (per API Token)
API Token erstellen
Meldet euch in Zabbix mit dem Benutzer an mit dessen Rechten das Skript die Abfragen machen soll (ich empfehle einen Super Admin) und ruft in den Benutzereinstellungen die API Tokens auf:
Dort geht Ihr oben rechts auf Create API Token:
Den Auth token kopiert euch weg, den braucht Ihr im Skript (im nächsten Schritt)
Skript auf Zabbix Server hinterlegen
Hinweis: Ich habe das Skript am 25.08.2024 an Zabbix 7.0 angepasst. Zum einen habe ich die Zeichenfolge "Bearer" von der Tokenangabe zu den Befehlsaufrufen verlegt.
Erstellt im externalscripts
Verzeichnis von Zabbix das folgende Skript:
nano /usr/lib/zabbix/externalscripts/zabbix_main_host.pl
Den genauen Pfad findet Ihr in der zabbix_server.conf
#!/usr/bin/perl
use strict;
use Getopt::Std;
use vars qw/ %opt /;
my $url = "http://localhost/api_jsonrpc.php"; # change <localhost> to your Zabbix WEB-FRONTEND Server if different!!!!
my $apitoken="euerapitoken";
my $maintenanceid;
#############
# Begin main
#
init();
my $hostname = $opt{s};
my $duration = $opt{d} || 10800;
my $maintname = $opt{n};
# Authenticate against Zabbix for API Maintenance addition
my $hostid = gethostid($hostname);
if($opt{r}){
print "Removing maintenance for host $hostname\n";
getmaintid($hostid,$maintname);
exit(0);
}else{
print "Adding maintenance for host $hostname\n";
addmaint($hostid,$duration,$maintname);
}
exit(0);
#########################
# Get command line input
#
sub init(){
my $opt_string = 'hrs:d:n:';
getopts( "$opt_string", \%opt ) or usage();
usage() if $opt{h};
usage() if !$opt{s};
usage() if !$opt{n};
}
#####################
# Print script usage
#
sub usage(){
print STDERR << "EOF";
usage: $0 [-hr] -s hostname [-d duration] -n name
-h : This (help) message
-r : Remove maintenance for specified host
-s hostname : Hostname in Zabbix
-d : Duration of maintenance in seconds. Leave blank to use default.
300 = 5 minutes
1800 = 30 minutes
3600 = 1 hour
10800 = 3 hour (default)
-n name : unique identifier
-s and -n are required
example: $0 -s hostname -d 3600 -n backup
example: $0 -s hostname -r -n backup
EOF
exit;
}
#############################################
# Zabbix API requests require authentication
#
#sub newrequest {
# my ($url, $user, $password) = @_;
#
# my $authenticate = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
# "params": {
# "password": "$password",
# "user": "$user"
# },
# "jsonrpc": "2.0",
#"method": "user.login",
#"id": 0
#}' $url | grep result | head -n 1 | cut -d '"' -f 8);
#my $auth = `$authenticate`;
#chomp($auth);
#return $auth
#
#}
###################################################
# Subroutine to query Zabbix to get host id
#
sub gethostid{
my $hostname = shift;
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: Bearer $apitoken' -d '{
"params": {
"filter": {
"name": "$hostname"
}
},
"jsonrpc": "2.0",
"method": "host.get",
"id": 2 }' $url);
my $res = `$process`;
chomp($res);
# print "$res \n\n";
my @output = split(/,/,$res);
my $x=0;
foreach(@output){
if (($output[$x] =~ m/\"host\"/)&&($output[$x] =~ m/$hostname/)){
$output[$x-2] =~ s/\[\{//g;
$output[$x-2] =~ s/"//g;
$output[$x-2] =~ s/hostid://g;
$output[$x-2] =~ s/result://g;
$output[$x-2] =~ s/\{//g;
$hostid = $output[$x-2];
}
$x++;
}
if(!$hostid){
print "WARNING - $hostname not found in maintenance for Zabbix.\n";
exit(1);
}
print "Host ID: ".$hostid."\n";
return $hostid
}
###################################################
# Subroutine to query Zabbix to get maintenance id
#
sub getmaintid{
my $hostid = shift;
my $maintname = shift;
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: Bearer $apitoken' -d '{
"params": {
"output": "extend",
"selectHosts": "refer",
"selectGroups": "refer",
"search": {
"description": "*$hostname*"
},
"searchWildcardsEnabled": true,
"searchByAny": true
},
"jsonrpc": "2.0",
"method": "maintenance.get",
"id": 2 }' $url);
my $res = `$process`;
print($res);
chomp($res);
my @output = split(/,/,$res);
my $x=0;
foreach(@output){
if (($output[$x] =~ m/\"name\"/)&&($output[$x] =~ m/ID $maintname/)){
$output[$x-1] =~ s/\[\{//g;
$output[$x-1] =~ s/"//g;
$output[$x-1] =~ s/maintenanceid://g;
$output[$x-1] =~ s/result://g;
$output[$x-1] =~ s/\{//g;
$maintenanceid = $output[$x-1];
remmaint($maintenanceid);
}
$x++;
}
if(!$maintenanceid){
print "WARNING - $hostname not found in maintenance for Zabbix.\n";
exit(1);
}
}
#################################################
# Subroutine to add maintenance window to Zabbix
#
sub addmaint{
$hostid = shift;
$duration = shift;
$maintname = shift;
my $start = time();
my $end = ($start + $duration);
# my $auth = newrequest($url, $apiuser, $apipassword);
my $process = 'curl -k -s -i -X POST -H \'Content-Type: application/json-rpc\' -H \'Authorization: Bearer '.$apitoken.'\' -d "{
\"jsonrpc\":\"2.0\",
\"method\":\"maintenance.create\",
\"params\":[{
\"groupids\":[],
\"hostids\":[\"'.$hostid.'\"],
\"name\":\"000_Manually Maintenance Mode with ID '.$maintname.' - '.$start.'\",
\"maintenance_type\":\"0\",
\"description\":\"000_Manually Maintenance Mode for '.$hostname.' set by Linux-Admin\",
\"active_since\":\"'.$start.'\",
\"active_till\":\"'.$end.'\",
\"timeperiods\": [{
\"timeperiod_type\": 0,
\"start_date\": \"'.$start.'\",
\"period\": '.$duration.'}]
}],
\"id\":3}" '.$url;
my $res = `$process`;
chomp($res);
my @output = split(/,/,$res);
foreach(@output){
if ($_ =~ m/\"error/){
print "$_\n";
exit(1);
}
print "$_\n" if ($_ =~ m/\"result/);
}
}
#################################################
# Subroutine to remove maintenance window from Zabbix
#
sub remmaint{
$maintenanceid = shift;
my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -H 'Authorization: Bearer $apitoken' -d '{
"jsonrpc":"2.0",
"method":"maintenance.delete",
"params":["$maintenanceid"],
"id":2}' $url);
my $res = `$process`;
chomp($res);
my @output = split(/,/,$res);
foreach(@output){
print "$_\n" if ($_ =~ m/\"error/);
print "$_\n" if ($_ =~ m/\"result/);
}
}
Das Skript stammt fast 1:1 von https://www.zabbix.org/wiki/Perl_script_to_add/remove_Maintenance
Ich habe es an die neueren Zabbix-Versionen angepasst bzw. die Host-Abfrage repariert sowie das es selbst signierte Zertifikate ignoriert.
Dank an Christoph Schmocker welcher die Idee für die Anpassung an die neuen API-Token geleifert hat!
Ihr müsst in dem Skript die folgenden Zeilen anpassen:
my $url = "http://localhost/api_jsonrpc.php"; # change <zabbix server> to your zabbix server my $apitoken="Bearer bla123bla";
mit euren Daten. Die URL ist auf localhost
, das sollte immer passen. Ggf. muss das auf localhost/zabbix
geändert werden (je nachdem wie der Aufruf eures Zabbix Servers ist.
Wenn das Webinterface von Zabbix auf einem separaten Server installiert ist sollte ihr den entsprechenden DNS-Namen oder die IP dieses Servers eintragen. Das Skript selbst muss aber immer auf dem Zabbix-Server liegen.
Und ggf. https statt http
Im Anschluß müsst Ihr das Skript noch ausführbar machen:
chmod +x /usr/lib/zabbix/externalscripts/zabbix_main_host.pl
Skripts in Zabbix hinterlegen
Die Skripts findet Ihr unter
Bis Zabbix 6.2:br>
Ab Zabbix 6.4:
Wartung für Zeitraum X
Unter (bis Zabbix 6.2)
Administration ==> Scripts
bzw. ab Zabbix 6.4
Alerts ==> Scripts
legen wir ein neues Script an:
Bis Zabbix 6.2:
Name : Maintenance/1h Type : Script Execute on: Zabbix Server Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -d 3600 -n via_Popup_Menu 2>&1
Ab Zabbix 6.4:
Name : 1h Scope : Manual host action Menu path : Maintenance Type : Script Execute on: Zabbix Server Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -d 3600 -n via_Popup_Menu 2>&1
Am Ende sollte das so aussehen:
Bis Zabbix 6.2:
Ab Zabbix 6.4:
Unten könnte Ihr noch die Berechtigungen einstellen - so können auch Read-Only Benutzer einen Host in den Wartungsmodus setzen.
Das Skript könnt Ihr mehrmals klonen, ändert im Namen das 1h in den gewünschten Zeitraum, z.B. 4h und im Aufruf die 3600 auf die entsprechende Anzahl der Sekunden, z.B. 14400.
Wartung löschen
Diese Script löscht alle(!) zuvor erstellten Wartungspläne für den Host, egal ob noch gültig oder abgelaufen, die mit diesem Script erstellt wurden.
Bis Zabbix 6.2:
Name : Maintenance/Delete All Type : Script Execute on: Zabbix Server Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -r -n via_Popup_Menu 2>&1
Name : Delete All Scope : Manual host action Menu path : Maintenance Type : Script Execute on: Zabbix Server Commands : /usr/lib/zabbix/externalscripts/zabbix_main_host.pl -s "{HOST.HOST}" -r -n via_Popup_Menu 2>&1
Anwendung
Wir gehen in eine Ansicht in der man einen Hostnamen anklicken kann und man das übliche Popup-Menü erhält, zum Beispiel:
- Trigger Ansicht
- Event Ansicht
- Latest Data (wenn mehr als ein Host dargestellt wird)
- Maps
Dann kommt folgendes Menü:
Ich habe da noch ein paar mehr Einträge :-)
Per Klick auf eine der Stunden wird der Host nun unmittelbar in den Wartungsmodus versetzt, dazu wird für jeden Host ein einzelner Wartungsplan erstellt.
Es öffnet sich ein neues Fenster in welchen Ihr den Erfolg betrachten könnt:
Wenn wir nun unter den Wartungsplänen nachsehen findet wir dort den per Skript erstellten:
Den Wartungsplan könnt Ihr natürlich auch dort direkt löschen, der bleibt bestehen auch nachdem dieser ausgelaufen ist.
oder halt auch per Popupmenü:
Proxy
Ich hatte es gerade bei einen Kunden das es nicht lokal vom Zabbix-Server aus funktionierte.
Grund war das der Befehl curl
immer versucht hat die Seite über den Proxy aufzurufen - auch bei localost
.
Lösung:
Ergänzt alle(!) curl
Aufrufe im Skript um den Parameter
--noproxy localhost